/**
 * Created by no1 on 2014/9/3.
 */
'use strict';
var session = require('koa-generic-session');
var mysql = require('./mysql.js');
var MUsers = require('../model/users.js');
var MTags = require('../model/tags.js');
var thunkify = require('thunkify');
var md5 = require('md5');
var C = require('../config/index');
var F = require('../common/function');
var uid2 = require('uid2');
//var redisClient = require('redis').createClient();
//var wrapper = require('co-redis');
//var redisCo = wrapper(redisClient);
var _ = require('underscore');
_.str = require('underscore.string');
_.v = require('validator');
var slashes = require('slashes');
var redisCo = F.redisCo;
var mUserAddress = require('../model/mUserAddress');
var mActivity = require('../model/mActivity');
var imgRule = require('./imgRule');
var o2o_F = require('../common/o2ofunction');

/*
 * @todo API01 获取短信验证码
 * */
exports.sendVerification = function*(Env) {
  var fields = Env.I;

  // 验证2分钟内重复发送
  var ip = Env.ip;
  var exist = yield redisCo.exists('sms:IP_' + ip);
  var existVal = yield redisCo.get('sms:IP_' + ip);
  if (exist && existVal == 1) {
    return F.returnMsg(400, '尝试次数过多，请等待' + C.SMS.sms_interval / 60 + '分钟后再试', 1);
  }

  //判断手机号码是否有效
  var mobile = fields.mobile;
  var act = fields.act;//action 1/11注册 2/12重置密码
  if (!F.isMobile(mobile)) {
    return F.returnMsg(400, '手机号码无效', 1);
  }

  var isExist = yield F.existMobile(mobile);//查找手机号码是否存在（重置密码）
  if (act == 2 || act == 12) {//重置密码（1注册2重置密码）
    if (!isExist) {//判断手机号码是否存在
      return F.returnMsg(400, '此手机号码未注册过', 1);
    }
    if (parseInt(mobile) >= 18900000000 && parseInt(mobile <= 19999999999)) {//内部测试
      return F.returnMsg(200, '验证码已发送', 1);
    } else {
      var verCode = F.getRandom(5);
      var flag = yield F.sendSMS(mobile, '找回密码验码[' + verCode + '],有效期为' + parseInt(C.verificationTimeOut) / 60 + '分钟');
      if (flag) {
        F.redisClient.SETEX('sms:verCode_' + mobile, C.verificationTimeOut, verCode);//保存验证码
        F.redisClient.SETEX('sms:IP_' + ip, C.SMS.sms_interval, 1);
        return F.returnMsg(200, '验证码已发送', 1);
      } else {
        return F.returnMsg(400, '验证码发送失败', 1);
      }
    }
  } else if (act == 1 || act == 11) { // 注册
    if (isExist) {//判断手机号码是否存在
      return F.returnMsg(400, '此手机号码已注册过', 1);
    }
    if (parseInt(mobile) >= 18900000000 && parseInt(mobile <= 19999999999)) {//内部测试
      return F.returnMsg(200, '验证码已发送', 1);
    } else {
      var verCode = F.getRandom(5);
      var flag = yield F.sendSMS(mobile, '感谢您注册瓷肌，注册验码[' + verCode + ']有效期为' + parseInt(C.verificationTimeOut) / 60 + '分钟');
      if (flag) {
        F.redisClient.SETEX('sms:verCode_' + mobile, C.verificationTimeOut, verCode);//保存验证码
        F.redisClient.SETEX('sms:IP_' + ip, C.SMS.sms_interval, 1);
        return F.returnMsg(200, '验证码已发送', 1);
      } else {
        return F.returnMsg(400, '验证码发送失败', 1);
      }
    }
  }
};


/*
 *@todo  API02 获取短信验证凭证
 * */
exports.registerTicket = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var act = fields.act;
  var mobile = fields.mobile;//手机
  var password = fields.password;
  var verCode = fields.ticketCode;//验证码
  //var existCode=yield redisCo.get('reg:ticket_'+mobile);
  var existCode = yield redisCo.get('sms:verCode_' + mobile);
  var timesExists = yield redisCo.exists('sms:trytimes_' + mobile);
  var timesVal = yield redisCo.get('sms:trytimes_' + mobile);
  timesVal = parseInt(timesVal);

  if (C.env != 'production' && verCode == 88888 && parseInt(mobile) >= 18900000000 && parseInt(mobile) <= 19999999999) { //非正式环境，验证码 81818 默认通过。
    var ticket = uid2(32);
    existCode = 88888;
    if (act == 1) {
      F.redisClient.SETEX('reg:ticket_' + mobile, C.user.regExp, ticket);
      return F.returnMsg(200, '短信验证成功', 1, {'ticket': ticket});
    }
  }

  if (!timesExists) {
    timesVal = 0;
  }
  if (act == 2 || act == 3) {
    //当act=2或者act=3的时候，验证服务器生成的ticket code
    existCode = yield redisCo.get('reg:ticket_' + mobile);
  } else if (act == 4) {//验证用户当前的密码
    if (!loginStatus.status) {
      return F.returnMsg(401, '登录用户才能继续操作', 1);
    }
    let uid = parseInt(loginStatus.uid);
    let userData = yield MUsers.getUser("password,salt", "uid=?", [uid]);
    if (userData.length > 0 && userData[0]['password'] == md5.digest_s(password + userData[0]['salt'])) {
      return F.returnMsg(200, '密码验证成功', 1);
    } else {
      return F.returnMsg(400, '密码验证失败', 1);
    }
  }

  if (timesExists && timesVal > 5) {
    return F.returnMsg(400, '尝试次数过多，请10分钟后再尝试', 1);
  } else {
    if (verCode == existCode && mobile != '') {
      F.redisClient.del('sms:verCode_' + mobile);//当验证客户端的验证码通过后，删除验证码
      F.redisClient.del('sms:trytimes_' + mobile);
      if (act == 1) {
        var ticket = uid2(32);
        F.redisClient.SETEX('reg:ticket_' + mobile, C.user.regExp, ticket);
        return F.returnMsg(200, '短信验证成功', 1, {'ticket': ticket});
      } else if (act == 2 || act == 3) {
        if (fields.tokenkey != undefined) {//没传tokenkey,返回提示信息必须先登录
          if (!loginStatus.status) {
            return F.returnMsg(401, '登录用户才能继续操作', 1);
          } else {
            let uid = parseInt(loginStatus.uid);
            //20151012 --取消验证是否已经绑定过手机，以便用户重复绑定手机号码
            let isMobileExist = yield mysql.query('select mobile,uid from mh_user where mobile=?', [mobile]);
            if (isMobileExist.length > 0) {
              if (isMobileExist[0].uid == uid) {
                if (act == 2) {//如果只是绑定手机操作，则直接返回
                  return F.returnMsg(400, '该手机已被您绑定，无需再次绑定', 1);
                }
              } else {
                return F.returnMsg(400, '绑定失败，该手机号码已被其他用户绑定', 1);
              }
            }
            if (act == 2) {
              let ret = yield mysql.query('update mh_user set mobile=? where uid=?', [mobile, uid]);
              if (ret.affectedRows > 0) {
                let key = C.redisPre.user_info;
                key = _.str.sprintf(key, parseInt(uid));
                F.redisClient.del(key);
                //更新Mongo数据库mobile信息（由mongo判断是否存在该uid用户）
                yield o2o_F.o2oUpdateUserInfo({uid: uid, mobile: mobile});
                return F.returnMsg(200, '绑定手机成功', 1);
              } else {
                return F.returnMsg(401, '绑定手机失败，请重试', 3);
              }
            } else if (act == 3) {
              var salt = F.getRandom(6);
              var result = yield mysql.query('UPDATE mh_user SET password = ?, salt = ?, mobile = ? where uid=?', [md5.digest_s(password + salt), salt, mobile, uid]);
              if (result && result.affectedRows >= 1) {
                let key = C.redisPre.user_info;
                key = _.str.sprintf(key, parseInt(uid));
                F.redisClient.del(key);//清楚个人信息缓存，以显示手机号码
                return F.returnMsg(200, '手机与密码设置成功', 1);
              } else {
                return F.returnMsg(400, '操作失败', 3);
              }
            }
          }
        }
        else {
          return F.returnMsg(401, '请先传入tokenkey参数', 3);
        }
      }
      else if (act == 11) {
        var session = Env.session;
        session.verOk = 1;
        return F.returnMsg(200, '短信验证成功', 1);
      }
    } else {
      F.redisClient.SETEX('sms:trytimes_' + mobile, C.login.login_lockInterval, timesVal + 1);
      return F.returnMsg(400, '手机号码无效或验证码不匹配', 1);
    }
  }
};

/*
 *@todo  API03 注册
 * parms post过来的数据
 * return 注册成功返回true失败返回false
 */
exports.register = function* (Env) {
  var fields = Env.I;
  var act = fields.act;//1app端手机注册，11web端 ，2 第三方账户注册
  var gender = 2;//注册时性别默认为女
  if (act != 2) {//2为第三方登录，不需要手机
    var mobile = parseInt(fields.mobile);
    var isMobile = F.isMobile(mobile);
    if (!isMobile) {
      return F.returnMsg(400, '手机号码格式不对', 1);
    }
    var userData = yield MUsers.getUser("uid", "mobile=?", [mobile]);//检注册的手机是否存在
    if (userData.length > 0) return F.returnMsg(400, '手机号码已注册过！', 1);
  }
  if (act == 1) {//app端
    var ticket = fields.ticket;
    var tempTicket = yield redisCo.get("reg:ticket_" + mobile);
    if (ticket != tempTicket) {
      return F.returnMsg(400, '注册过时,注册必须在' + parseInt(C.user.regExp) / 60 + '分钟内完成', 1);
    }
  }
  if (act == 2) {//第三方登录注册
    var ticket = fields.ticket;
    var tempTicket = yield redisCo.hmget('reg:ticket_' + ticket, ['ticket', 'mediatype', 'openid', 'accesstoken', 'gender', 'expires_in', 'unionid', 'media_data']);
    if (tempTicket[0] != ticket) {
      return F.returnMsg(400, '注册过时,注册必须在' + parseInt(C.user.regExp) / 60 + '分钟内完成', 1);
    }
    gender = tempTicket[4];//获得第三方账号的性别
    var expiresIn = tempTicket[5];
    var unionid = tempTicket[6];
    var meidaData = tempTicket[7];
    var accessToken = tempTicket[3];
    //判断第三方验证是否成功，不成功则直接返回
    let json_mediaData = JSON.parse(meidaData);
    if (json_mediaData.errcode && json_mediaData.errcode > 0) {
      return F.returnMsg(400, '注册失败,第三方媒体授权失败', 1);
    }
  }
  if (act == 11) {//web端
    var session = Env.session;
    if (session.verOk != 1) {
      return F.returnMsg(400, '注册过时,注册必须在' + parseInt(C.user.regExp) / 60 + '分钟内完成', 1);
    }
  }
  var ip = Env.ip || '';//客户端ip
  var flag = false;//标记注册是否成功
  var nickName = fields.nickname != undefined ? _.str.trim(fields.nickname) : '';
  var bodyType = fields.bodytype != undefined ? fields.bodytype : 0;
  var regIp = ip;
  var lastloginIp = ip;
  if (act != 2) {//第三方注册不需密码
    var salt = F.getRandom(6);//随机六位数
    var password = fields.password;
    if (password == undefined) {
      return F.returnMsg(400, '密码不能为空', 1);
    }
    password = md5.digest_s(password + salt);
  }
  if (nickName !== '') { // 传了昵称
    //昵称不能包含‘瓷肌’二字
    if (nickName.indexOf('瓷肌') > -1) {
      return F.returnMsg('400', '昵称不能\'瓷肌\'二字，请更换昵称', 1);
    } else {
      let reg = /^.*瓷.{0,3}肌.*$/;
      if (reg.test(nickName)) {
        return F.returnMsg('400', '昵称不能\'瓷肌\'二字，请更换昵称', 1);
      }
    }
    userData = yield MUsers.getUser("uid", "nickname=?", [nickName]);//检查注册的昵称是否存在
    if (userData.length > 0) return F.returnMsg(400, '昵称已注册过！', 1);
  }
  if (nickName === '') { //如未定义昵称，则自动生成不重复的昵称
    var newNickName;
    var nickExist;
    do {
      newNickName = '瓷娃' + F.getRandom(8);
      nickExist = yield MUsers.getUser("uid", "nickname=?", [newNickName]);//检查昵称是否存在
    }
    while (nickExist.length > 0);
    nickName = newNickName;
  }
  var newUid = 0;//保存新注册的用户id
  var face = _.random(1, 32);
  if (act != 2) {
    var newUser = yield mysql.query("insert into mh_user(nickname,mobile,password,salt,bodytype,regtime,regip,lastlogintime,lastloginip,face) values(?,?,?,?,?,UNIX_TIMESTAMP(),?,UNIX_TIMESTAMP(),?,?)", [nickName, mobile, password, salt, bodyType, regIp, lastloginIp, face]);
  } else {/////////////第三方注册没有手机跟密码
    var mediaType = tempTicket[1];
    var newUser = yield mysql.query("insert into mh_user(nickname,bodytype,regtime,regip,lastlogintime,lastloginip,face,mediatype) values(?,?,UNIX_TIMESTAMP(),?,UNIX_TIMESTAMP(),?,?,?)", [nickName, bodyType, regIp, lastloginIp, face, parseInt(mediaType)]);
  }
  newUid = newUser.insertId;
  if (newUid > 0) {
    mysql.query("insert into mh_user_info(uid,gender) values(?,?)", [newUid, gender]);
    flag = true;
  }
  if (flag) {
    // 4x0位tokenkey
    var newTokenkey = uid2(40);

    F.redisClient.hmset('siss:user:uid_' + newUid, 'uid', newUid, 'groupid', 10, 'nickname', nickName);//保存会话
    F.redisClient.expire('siss:user:uid_' + newUid, C.session.ttl);
    yield MUsers.updateToken(newUid, newTokenkey);
    if (act == 1 || act == 2) {//app端和第三方
      if (act == 1) {//app端
        F.redisClient.del("reg:ticket_" + mobile);
      } else {//第三方
        var openId = tempTicket[2];
        expiresIn = F.timestamp() + parseInt(expiresIn);
        var flag = yield mysql.query('INSERT INTO mh_users_token(uid,mediatype,openid,timeline,access_token,expires_in,unionid,media_data) VALUES(?,?,?,UNIX_TIMESTAMP(),?,?,?,?)', [newUid, mediaType, openId, accessToken, expiresIn, unionid, meidaData]);
        if (flag.affectedRows > 0) {
          F.redisClient.del("reg:ticket_" + ticket);
        }
      }
      F.redisClient.SETEX('siss:user:token_' + newTokenkey, C.session.ttl, newUid);
      var bigface = F.generateFaceUrl(face, newUid, 1);
      var minFace = F.generateFaceUrl(face, newUid);
      var gain = yield F.generateIntegralLog(newUid, 1);
      // 通过IP获取所在地
      if (ip.length > 0) {
        F.ip2city(ip, function (error, citycode) {
          console.log('CITYCODE:' + citycode);
          if (!error && citycode != '') {
            mysql.query('update mh_user_info set citycode = ? where uid=?', [citycode, newUid],
              function (error, results) {
                if (error) {
                  console.log("ERROR: 通过IP获取所在地" + error.message);
                }
              }
            );
          }
        });
      }

      return F.returnMsg(200, {act: '注册成功', e: gain}, 4, {
        'uid': newUid,
        'tokenkey': newTokenkey,
        'face': bigface,
        'minface': minFace,
        'nickname': nickName
      });
    } else if (act == 11) {//web端
      session.verOk = null;
      session.uid = newUid;
      return F.returnMsg(200, '注册成功', 3, {'uid': newUid});
    }
  } else {
    return F.returnMsg(400, '注册失败', 1);
  }
};


/*
 *@todo  API04 登录
 * */
exports.login = function* (Env) {
  var fields = Env.I;
  var apiVer = fields.apiVer;//版本号
  var mobile = fields.mobile;
  var password = fields.password;
  var act = fields.act;
  let testInfo = fields.isTest || '';
  let region_data = yield F.getUserCityData(Env.ip);
  if (!F.isMobile(mobile)) {//判断手机号码格式是否正确
    return F.returnMsg(400, '手机号码格式不正确', 1);
  }
  var attemptLimit = C.login.login_attemptLimit;
  var attempts = yield redisCo.get(C.login.login_attemptCountPrefix + mobile);
  attempts = attempts || 0;
  if (attempts >= attemptLimit) {
    return F.returnMsg(400, '尝试次数过多，请等待5分钟后再试', 1);
  }
  var userData = yield MUsers.getUser("uid,groupid,password,salt,nickname,mobile,tokenkey,face", "mobile=?", [mobile]);
  if (userData.length > 0 && userData[0]['groupid'] == 5) {// group=5 时，禁止登录
    // 记录登录日志
    F.loginLog(userData[0]['uid'], 1, Env.ip, region_data);
    return F.returnMsg(400, '您的账号或被外星人挟持，请更换或重新申请账号登录', 1);
  } else if (C.env != 'production' && testInfo == 'csapp') {
    if (userData.length > 0 && userData[0]['password'] == _.str.trim(password)) {
      var newTokenkey = uid2(40);
      F.redisClient.expire('siss:user:uid_' + userData[0]['uid'], C.session.ttl);
      F.redisClient.SETEX('siss:user:token_' + newTokenkey, C.session.ttl, userData[0]['uid']);
      yield MUsers.updateToken(userData[0]['uid'], newTokenkey);
      return F.returnMsg(200, '登录成功', 3, {
        uid: userData[0]['uid'],
        tokenkey: newTokenkey,
        nickname: userData[0]['nickname'],
        groupid: userData[0]['groupid']
      });
    }
  }
  else if (userData.length > 0 && userData[0]['password'] == md5.digest_s(password + userData[0]['salt'])) {//用户存在
    // 记录登录日志
    F.loginLog(userData[0]['uid'], 1, Env.ip, region_data);
    var newTokenkey = uid2(40);
    if (F.isManager(userData[0]['groupid'])) {
      F.redisClient.hmset('siss:user:uid_' + userData[0]['uid'], 'uid', userData[0]['uid'], 'groupid', userData[0]['groupid'], 'nickname', userData[0]['nickname'], 'vestuid', userData[0]['uid'], 'vestnickname', userData[0]['nickname']);//保存会话
    } else {
      F.redisClient.hmset('siss:user:uid_' + userData[0]['uid'], 'uid', userData[0]['uid'], 'groupid', userData[0]['groupid'], 'nickname', userData[0]['nickname']);//保存会话
    }
    F.redisClient.expire('siss:user:uid_' + userData[0]['uid'], C.session.ttl);
    if (act == 1 || act == 2) {//act=1 手机端 act=2 pc端
      F.redisClient.SETEX('siss:user:token_' + newTokenkey, C.session.ttl, userData[0]['uid']);
      // 40位tokenkey
      yield MUsers.updateToken(userData[0]['uid'], newTokenkey);
      if (act == 2) {
        return F.returnMsg(200, '登录成功', 3, {
          uid: userData[0]['uid'],
          tokenkey: newTokenkey,
          nickname: userData[0]['nickname'],
          groupid: userData[0]['groupid']
        });
      }
      var face = F.generateFaceUrl(userData[0]['face'], userData[0]['uid'], 1);
      var minFace = F.generateFaceUrl(userData[0]['face'], userData[0]['uid']);
      return F.returnMsg(200, '登录成功', 3,
        {
          uid: userData[0]['uid'],
          nickname: userData[0]['nickname'],
          mobile: userData[0]['mobile'],
          face: face,
          minface: minFace,
          tokenkey: newTokenkey
        });
    } else if (act == 11) {
      var session = Env.session;
      session.uid = userData[0]['uid'];
      return F.returnMsg(200, '登录成功', 3, {
        uid: userData[0]['uid'],
        nickname: userData['nickname']
      });
    }
  } else {
    F.redisClient.SETEX(C.login.login_attemptCountPrefix + mobile, C.login.login_lockInterval, (parseInt(attempts) + 1));
    return F.returnMsg(400, '手机号码或密码不匹配，还有 ' + (attemptLimit - attempts) + '次尝试机会', 1);
  }
};

/*
 *@todo  API05 登出
 */
exports.logout = function*(Env) {
  var fields = Env.I;
  var act = fields.act;
  if (act == 1) {
    var tokenKey = fields.tokenkey;
    F.redisClient.del('siss:user:token_' + tokenKey);
  } else if (act == 11) {
    var session = Env.session;
    session.uid = null;
  }
  return F.returnMsg(200, '退出成功', 3);
};

/*
 *@todo  API06 获取个人资料
 * */
exports.getUserinfo = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var apiVer = fields.apiVer;//版本号
  var uid = fields.uid || loginStatus.uid;
  var manager = fields.manager;
  var page = fields.page || 1;
  var pageSize = fields.pagesize != undefined ? parseInt(fields.pagesize) : C.threadlist.pageSize;
  var beginIndex = (page - 1) * pageSize;
  let act = fields.act || 0;
  if (!loginStatus.status && !uid) {
    if (act != 2) {
      return F.returnMsg('401', '身份验证失败,请先登陆', 3);
    }
  }
  if (parseInt(act) == 2) {
    if (!(manager && manager == 1 && F.isManager(loginStatus.groupid))) {
      return F.returnMsg('300', '权限不足，获取失败.', 1);
    } else {
      let user_device_arr = [];
      let ret_user_device_arr = [];
      let val_arr = [beginIndex, pageSize];
      let sqlWhereuid = '';
      if (fields.uid && parseInt(fields.uid) > 0) {
        sqlWhereuid = ' and mu.uid=? ';
        val_arr.unshift(fields.uid);
      }
      let userDeviceData = yield mysql.query('SELECT distinct mul.device_id,mu.uid,mu.nickname from mh_user_log mul LEFT JOIN mh_user mu on mul.uid=mu.uid where LENGTH(mul.device_id)>0 '
        + sqlWhereuid + ' ORDER BY mul.device_id,mu.uid LIMIT ?,?', val_arr);
      if (userDeviceData.length == 0) {
        return F.returnMsg(300, '没有数据了', 1);
      }
      for (let userDevice of userDeviceData) {
        if (!_.v.isIn(userDevice.device_id, user_device_arr)) {
          if (!_.v.isIn(userDevice.device_id, user_device_arr)) {
            user_device_arr.push(userDevice.device_id);
          }
          let user_device = {device_id: userDevice.device_id};
          user_device.users = [];
          let user_array = _.filter(userDeviceData, function (user) {
            return user.device_id == userDevice.device_id;
          });
          user_array.forEach(function (obj) {
            user_device.users.push({uid: obj.uid, nickname: obj.nickname});
          });
          ret_user_device_arr.push(user_device);
        }
      }
      return F.returnMsg('200', '获取成功', 3, ret_user_device_arr);
    }
  }

  var userInfo = yield F.returnUserInfo(uid);
  userInfo = userInfo[0];
  //var userInfo = yield mysql.queryOne('SELECT u.uid, u.nickname, u.groupid,u.face, u.bodytype, ui.threads, ui.friends, ui.fans, ui.tfavtimes, ui.gender, ui.signature,ui.pintagtimes as pinTags,ui.beliked FROM mh_user u LEFT JOIN mh_user_info ui on u.uid = ui.uid WHERE u.uid = ?',uid);
  if (userInfo) {
    if (userInfo.hasOwnProperty('face')) {
      var face = userInfo.face;
      userInfo.face = F.generateFaceUrl(face, uid, 1);
      userInfo.minface = F.generateFaceUrl(face, uid);
    }
    userInfo.friendStatus = false;
    if (loginStatus.status) {
      var isFriend = yield MUsers.isFriend(loginStatus.uid, uid);
      if (isFriend) {
        userInfo.friendStatus = true;
      } else if (_.v.isIn(uid, C.sns.manager_uid)) {  //if (_.v.isIn(fuid, C.sns.manager_uid)){ //判断是否系统发言用户
        userInfo.friendStatus = true;
      }
      if (parseInt(loginStatus.uid) != uid) {
        mysql.query('INSERT INTO mh_user_viewlog(uid,timeline,uid1) VALUES(?,UNIX_TIMESTAMP(),?)', [parseInt(loginStatus.uid), uid]);
      }
    }

    if (!(manager && manager == 1 && F.isManager(loginStatus.groupid))) {
      delete userInfo.name;
      delete userInfo.groupid;
    }
    userInfo.alterpwd = false;//允许修改密码（有手机时可以修改）
    if (userInfo.mobile != '') {
      userInfo.alterpwd = true;
    }
    if (uid != loginStatus.uid) { //不是查本人资料
      delete userInfo.mobile;
      delete userInfo.hasPassword;
    }
    //如果是自己查看自己的信息时，动态读取发帖数
    if (act == 1 && fields.tokenkey != undefined && loginStatus.uid > 0) {
      let userThreads = yield mysql.queryOne('SELECT count(1) as threads from mh_thread where uid=? and `status` IN(1,2)', [uid]);
      userInfo.threads = parseInt(userThreads['threads']);
      let user3rdbindInfo = yield F.get3rdBindInformation(uid);
      userInfo.QQ = user3rdbindInfo.QQ;
      userInfo.WX = user3rdbindInfo.WX;
    }

    userInfo.friends += C.sns.manager_uid.length;

    //增加系统发言人的关注数
    if ((loginStatus.status && loginStatus.uid == uid) || (manager && manager == 1 && F.isManager(loginStatus.groupid))) {
      console.log('userInfo.level',userInfo.level);
      var curlevel = F.getIntegralInfo(parseInt(userInfo.level));//获取当前等级信息
      console.log('curlevel',curlevel);
      //var nextlevel= F.getIntegralInfo(parseInt(userInfo.level)+1);//获取下一等级信息
      userInfo.currentlevel = curlevel[0].range_l;
      userInfo.nextlevel = curlevel[0].range_h + 1;
      userInfo.msg = ''; // '距升级还差'+(nextlevel[0].range_l-curlevel[0].range_l)+'分'
      userInfo.alowertalent = yield F.isAlowerTalent(userInfo);
    } else {
      delete userInfo.integral;
      delete userInfo.lastupgradetime;
      delete userInfo.lastsigntime;
      delete userInfo.signtimes;
    }
    return F.returnMsg('200', '获取个人信息成功', 3, userInfo);
  } else {
    return F.returnMsg('300', '获取个人信息失败', 1);
  }
};

/*
 *@todo  API07 修改个人资料
 * */
exports.setUserinfo = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var apiVer = fields.apiVer;//版本号
  // 身份验证
  if (!loginStatus.status) {
    return F.returnMsg('401', '身份验证失败', 3);
  }
  var name = fields.name;
  var nickname = fields.nickname;
  var btype = fields.btype;
  var signature = fields.signature;
  var gender = fields.gender;
  var uid = loginStatus.uid;
  var manager = fields.manager;
  var updateUserCache = {};
  var updateFieldsArray = [];
  var updateValueArray = [];

  var updateFieldsArrayI = [];
  var updateValueArrayI = [];
  var citycode = fields.citycode;

  // 管理员版主可修改其他用户
  if (manager && manager == 1 && F.isManager(loginStatus.groupid, [1, 2])) { // 判断是否1 管理员
    uid = parseInt(fields.uid) > 0 ? parseInt(fields.uid) : uid;
  }
  if (name != undefined && manager && manager == 1 && F.isManager(loginStatus.groupid, [1, 2])) {//修改姓名暂时只对后台开放
    name = _.str.trim(name);
    updateUserCache.name = name;
    updateFieldsArrayI.push('name=?');
    updateValueArrayI.push(name);
  }
  if (nickname != undefined) {
    nickname = _.str.trim(nickname);
    //昵称不能包含‘瓷肌’二字
    if (nickname.indexOf('瓷肌') > -1) {
      return F.returnMsg('400', '昵称不能\'瓷肌\'二字，请更换昵称', 1);
    } else {
      let reg = /^.*瓷.{0,3}肌.*$/;
      if (reg.test(nickname)) {
        return F.returnMsg('400', '昵称不能\'瓷肌\'二字，请更换昵称', 1);
      }
    }
    //检查昵称是否存在
    var nickExist = yield MUsers.getUser("uid", "nickname=? and uid<>?", [nickname, uid]);
    if (nickExist.length > 0) {
      return F.returnMsg('400', '昵称已存在，请更换昵称', 1);
    }
    var userData = yield mysql.queryOne('SELECT nickname FROM mh_user WHERE uid=?', [uid]);//取用户昵称
    var oldNickName = userData['nickname'];
    if (oldNickName != nickname) {//昵称是否修改
      var userThread = yield mysql.query('SELECT tid FROM mh_thread WHERE uid=? and `status`=1', [uid]);
      if (userThread.length > 0) {
        var tidArr = [];
        for (var i in userThread) {
          tidArr.push(userThread[i].tid);
        }
        var key = C.redisPre.thread_info;
        var expire = C.redisPre.thread_ttl;
        yield F.redisCo.mhupdatethread(4, key, expire, nickname, 'nickname', tidArr);//批量修改缓存帖子发帖人昵称
      }
      F.redisClient.hmset('siss:user:uid_' + uid, 'nickname', nickname);//保存会话昵称
    }
    updateUserCache.nickname = nickname;
    updateFieldsArray.push('nickname=?');
    updateValueArray.push(nickname);
  }

  if (btype != undefined) {
    updateUserCache.bodytype = parseInt(btype);
    updateFieldsArray.push('bodytype=?');
    updateValueArray.push((btype == '' || parseInt(btype) > 5) ? 0 : parseInt(btype));
  }

  if (gender != undefined) {
    updateUserCache.gender = parseInt(gender);
    updateFieldsArrayI.push('gender=?');
    updateValueArrayI.push((gender == '' || parseInt(gender) > 2) ? 0 : parseInt(gender));
  }

  if (signature != undefined) {
    updateUserCache.signature = signature;
    updateFieldsArrayI.push('signature=?');
    updateValueArrayI.push(signature);
  }

  if (citycode != undefined) {
    var cityInfo = F.getCityInfo(citycode);
    if (!_.isEmpty(cityInfo)) {
      updateUserCache.citycode = citycode;
      updateUserCache.city = (cityInfo.province != cityInfo.city ? cityInfo.province + ' ' + cityInfo.city : cityInfo.city);

      updateFieldsArrayI.push('citycode=?');
      updateValueArrayI.push(citycode);
    }
  }
  // 管理员、版主可修改用户组id
  if (fields.groupid != undefined && F.isManager(loginStatus.groupid)) {
    if (uid != loginStatus.uid) {
      var groupid = parseInt(fields.groupid) >= loginStatus.groupid ? parseInt(fields.groupid) : loginStatus.groupid; // 只能设置为大于等于自己groupid  即版主不能设置别人为管理员
      if ((groupid > loginStatus.groupid || loginStatus.groupid == 1) && parseInt(fields.uid) > 0) {
        if (groupid < 3 && (name == undefined || name == '')) {
          return F.returnMsg('400', '设为管理员或超级版主时,名字不能为空', 1);
        }
        updateUserCache.groupid = groupid;
        mysql.query('UPDATE mh_user SET groupid=? WHERE uid=?', [groupid, parseInt(fields.uid)]);

        var userInfo = yield redisCo.hmget('siss:user:uid_' + uid, ['uid', 'groupid', 'nickname', 'vestuid', 'vestnickname']);
        if (groupid == 5) {//如果是设为禁止访问组，删除登录信息
          F.redisClient.del('siss:user:uid_' + uid);
        }
        if (userInfo[0] != null && groupid != 5) {//存在缓存，且非禁止访问组 则重新设置组
          F.redisClient.hmset('siss:user:uid_' + uid,
            'groupid', groupid
          );
        }
      } else {
        return F.returnMsg('400', '修改个人资料失败', 1);
      }
    } else {
      return F.returnMsg('400', '不能改自己的用户组', 1);
    }
  }

  updateValueArray.push(uid);
  updateValueArrayI.push(uid);

  if (updateFieldsArray.length > 0) {
    var result = yield mysql.query('UPDATE mh_user SET ' + updateFieldsArray.join(',') + ' WHERE uid=?', updateValueArray);
    if (result.affectedRows < 1) {
      return F.returnMsg('400', '修改个人资料失败', 1);
    }
  }
  if (updateFieldsArrayI.length > 0) {
    var result = yield mysql.query('UPDATE mh_user_info SET ' + updateFieldsArrayI.join(',') + ' WHERE uid=?', updateValueArrayI);
    if (result.affectedRows < 1) {
      return F.returnMsg('400', '修改个人资料失败', 1);
    }
  }

  if (updateFieldsArray.length > 0 || updateFieldsArrayI.length > 0) {
    yield F.updateUserCache(parseInt(uid), updateUserCache);//更新用户缓存
    var userData = yield F.returnUserInfo(uid);
    return F.returnMsg('200', '成功', 3, {'city': userData[0].city});
  } else {
    return F.returnMsg('200', '无修改', 3);
  }
};

/*
 *@todo  API10 修改、重置用户密码
 * */
exports.changePassword = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var apiVer = fields.apiVer;//版本号
  var act = fields.act;
  var oldPassword = fields.oldpwd;
  var newPassword = fields.newpwd;

  var newSalt = F.getRandom(6);
  var result;
  if (act == 1 || act == 11) { //修改密码
    if (!loginStatus.status) {
      return F.returnMsg(401, '身份验证失败', 3);
    }
    var userData = yield MUsers.getUser('password,salt', 'uid=?', [loginStatus.uid]);
    if (userData.length > 0 && userData[0]['password'] != md5.digest_s(oldPassword + userData[0]['salt'])) {
      return F.returnMsg(400, '旧密码错误', 3);
    }
    var result = yield mysql.query('UPDATE mh_user SET password = ?, salt = ? WHERE uid = ?', [md5.digest_s(newPassword + newSalt), newSalt, loginStatus.uid]);
  } else if (act == 2 || act == 12) { // 重置密码
    var mobile = fields.mobile;
    if (act == 2) {//app端
      var ticket = fields.ticket;
      var tempTicket = yield redisCo.get('reg:ticket_' + mobile);
      if (ticket != tempTicket) {
        return F.returnMsg(400, '重置密码超时,重置密码必须在' + parseInt(C.user.regExp) / 60 + '分钟内完成', 1);
      }
    } else if (act == 12) {//web端
      var session = Env.session;
      if (session.verOk != 1) {
        return F.returnMsg(400, '重置密码过时,重置密码必须在' + parseInt(C.user.regExp) / 60 + '分钟内完成', 1);
      }
    }
    var result = yield mysql.query('UPDATE mh_user SET password = ?, salt = ? WHERE mobile = ?', [md5.digest_s(newPassword + newSalt), newSalt, mobile]);
  } else if (act == 3) {//用户APP端第三方登陆用户设置密码
    if (!loginStatus.status) {
      return F.returnMsg(401, '身份验证失败', 3);
    }
    var result = yield mysql.query('UPDATE mh_user SET password = ?, salt = ? WHERE uid = ?', [md5.digest_s(newPassword + newSalt), newSalt, loginStatus.uid]);
  }
  if (result && result.affectedRows >= 1) {
    return F.returnMsg(200, '密码设置成功', 1);
  } else {
    return F.returnMsg(400, '密码设置失败', 1);
  }
};

/*
 @todo API13 取头像又拍云上传秘钥
 */
exports.upyunImg = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '身份验证失败', 3);
  }
  var uid = fields.uid;
  var manager = fields.manager;
  if (uid && uid != loginStatus.uid && manager != 1 && !F.isManager(loginStatus.groupid, [1, 2])) {
    return F.returnMsg(400, '权限验证失败', 1);
  }
  var arr = {};
  arr['type'] = 1;
  arr['uid'] = uid ? uid : loginStatus.uid;
  var data = yield F.getUpyunSign(arr);
  if (fields.apiVerNum == 1) {//fields.apiVerNum==2，当头像上传成功时，需调api35
    mysql.query('update mh_user SET face=0 where uid=?', [loginStatus.uid]);
  }
  console.log(data);
  return F.returnMsg(200, '成功', 3, data);
};

/*
 *@todo API15 关注或取消关注某人
 * */
exports.friend = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能关注操作', 3);
  }
  var act = fields.act; // 1/11:关注 2/12:取消关注
  var fuid = parseInt(fields.uid);//被关注人
  var uid = loginStatus.uid;//登录人id
  var nickName = loginStatus.nickname;//登录人昵称
  if (F.isManager(loginStatus.groupid)) {//管理员发帖
    uid = loginStatus.vestuid;
    nickName = loginStatus.vestnickname;
  }

  if (uid == fuid) {
    return F.returnMsg(400, '不能关注自己', 1);
  }

  // 检查要关注的用户是否存在
  var isUserExist = yield MUsers.getUser('uid,os_type,device_token', 'uid=?', [fuid]);
  if (isUserExist.length == 0) {
    return F.returnMsg(300, '用户不存在', 1);
  }
  var result = '';
  var isFriend = yield mysql.query('SELECT uid FROM mh_friend WHERE uid=? AND fuid=?', [uid, fuid]);
  if (act == 1 || act == 11) { //关注
    // 判断是否已经关注
    if (isFriend.length <= 0) {
      // 添加好友关系
      result = yield mysql.query('INSERT ignore INTO mh_friend(uid,fuid,timeline) values(?,?,UNIX_TIMESTAMP())', [uid, fuid]);
      if (result.affectedRows < 1) {
        return F.returnMsg(300, '你已经关注过此好友了', 1);
      }
      // 自己好友数加1
      mysql.query('UPDATE mh_user_info SET friends=friends+1 WHERE uid=?', [uid]);
      //更新关注人信息开始
      var key = C.redisPre.user_info;
      key = _.str.sprintf(key, parseInt(uid));
      var temp = yield F.redisCo.EXISTS(key);
      if (temp == 1) {
        F.redisClient.HINCRBY(key, 'friends', 1);//好友+1
      }
      //更新关注人信息结束

      // 对方粉丝加1
      mysql.query('UPDATE mh_user_info SET fans=fans+1 WHERE uid=?', [fuid]);
      //更新被关注人信息开始
      key = C.redisPre.user_info;
      key = _.str.sprintf(key, parseInt(fuid));
      temp = yield F.redisCo.EXISTS(key);
      if (temp == 1) {
        F.redisClient.HINCRBY(key, 'fans', 1);//好友+1
      }
      //更新被关注人信息结束

      //重新生成用户好友缓存开始
      key = C.redisPre.user_list;
      key = _.str.sprintf(key, uid, 2);
      temp = yield F.redisCo.EXISTS(key);
      if (temp == 1) {
        var arr = [];
        arr[0] = key;
        arr.push(F.timestamp());
        arr.push(fuid);
        yield redisCo.ZADD(arr);
      } else {
        yield F.userList(parseInt(uid), 2);
      }

      //重新生成用户好友缓存结束

      yield F.addDynamicInfo(uid, 3, fuid);
      // 被关注的是马甲，不推送
      if (!F.isVest(fuid)) {
        result = yield mysql.queryOne('SELECT pushfriend,pushdisturb FROM mh_user_info WHERE uid=?', [fuid]);
        if (result && result['pushfriend'] == 1 && F.disturb(parseInt(result['pushdisturb']))) {
          F.umengSendMsg(isUserExist[0]['os_type'], isUserExist[0]['device_token'], 1, {
            nickname: nickName,
            uid: uid
          });//友盟推送
        }
      }
      var gain = yield F.generateIntegralLog(uid, 7, fuid);//关注成功后获得积分
    } else {
      return F.returnMsg(300, '你已经关注过此好友了', 1);
    }
    yield F.afterFriend();
    return F.returnMsg(200, {act: '关注成功', e: gain}, 4, {uid: fuid, friend: true});
  } else { // 取消关注
    if (_.v.isIn(fuid, C.sns.manager_uid)) { //判断是否系统发言用户
      return F.returnMsg(400, '此系统用户，不能取消关注', 1);
    }
    if (isFriend.length > 0) {
      // 删除好友关系
      result = yield mysql.query('DELETE FROM mh_friend WHERE uid=? AND fuid=?', [uid, fuid]);
      if (result.affectedRows < 1) {
        return F.returnMsg(400, '失败', 1);
      }

      var friends = yield mysql.queryOne('SELECT friends FROM mh_user_info WHERE uid=?', [uid]);
      if (parseInt(friends['friends']) > 0) {
        // 自己好友数减1
        mysql.query('UPDATE mh_user_info SET friends=friends-1 WHERE uid=? AND friends>0', [uid]);
        //更新关注人信息开始
        var key = C.redisPre.user_info;
        key = _.str.sprintf(key, parseInt(uid));
        var temp = yield F.redisCo.EXISTS(key);
        if (temp == 1) {
          F.redisClient.HINCRBY(key, 'friends', -1);//好友-1
        }
        //更新关注人信息结束
      }

      var fans = yield mysql.queryOne('SELECT fans FROM mh_user_info WHERE uid=?', [fuid]);
      if (parseInt(fans['fans']) > 0) {
        // 对方粉丝减1
        mysql.query('UPDATE mh_user_info SET fans=fans-1 WHERE uid=? AND fans>0', [fuid]);
        //更新被关注人信息开始
        var key = C.redisPre.user_info;
        key = _.str.sprintf(key, parseInt(fuid));
        temp = yield F.redisCo.EXISTS(key);
        if (temp == 1) {
          F.redisClient.HINCRBY(key, 'fans', -1);//粉丝-1
        }
        //更新被关注人信息结束
      }
      //重新生成用户好友缓存开始
      key = C.redisPre.user_list;
      key = _.str.sprintf(key, uid, 2);
      temp = yield F.redisCo.EXISTS(key);
      if (temp == 1) {
        F.redisClient.ZREM(key, fuid);
      }
      //重新生成用户好友缓存结束
      var gain = yield F.generateIntegralLog(uid, 8, fuid);//关注成功后获得积分
    }
    yield F.afterFriend();
    return F.returnMsg(200, {act: '取消关注成功', e: gain}, 4, {uid: fuid, friend: false});
  }
};

/*
 *@todo API17 订阅或取消订阅某标签
 * */
exports.pinTag = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var act = fields.act; // 1/11:订阅 2/12:取消订阅
  if (!loginStatus.status && (act == 1 || act == 2 || act == 11 || act == 12)) {
    return F.returnMsg(401, '登录用户才能订阅操作', 3);
  }
  var tagid = parseInt(fields.tagid);
  var uid = parseInt(loginStatus.uid);

  var uid = loginStatus.uid;//登录人id
  if (F.isManager(loginStatus.groupid)) {//管理员发帖
    uid = loginStatus.vestuid;
  }
  // 检查要订阅的标签是否存在
  var isTagExist = yield MTags.isTagExist(tagid);
  if (!isTagExist) {
    return F.returnMsg(300, '标签不存在', 1);
  }
  if (loginStatus.status) {
    var isPinTag = yield mysql.query('SELECT uid FROM mh_pintag WHERE uid=? AND tagid=?', [uid, tagid]);
  }
  var gain = 0;
  if (act == 1 || act == 11) { //订阅
    // 判断是否已经订阅
    if (isPinTag.length <= 0) {
      // 添加订阅
      var result = yield mysql.query('INSERT INTO mh_pintag(uid,tagid,timeline) VALUES(?,?,UNIX_TIMESTAMP())', [uid, tagid]);
      if (result.affectedRows < 1) {
        return F.returnMsg(400, '失败', 1);
      }
      // 用户订阅数加1
      mysql.query('UPDATE mh_user_info SET pintagtimes=pintagtimes+1 WHERE uid=?', [uid]);
      //更新订阅人信息开始
      var key = C.redisPre.user_info;
      key = _.str.sprintf(key, uid);
      var temp = yield F.redisCo.EXISTS(key);
      if (temp == 1) {
        F.redisClient.HINCRBY(key, 'pinTags', 1);//用户订阅数+1
      }
      //更新订阅人信息结束
      // 标签订阅数加1
      mysql.query('UPDATE mh_tags SET pincount=pincount+1 WHERE tagid=?', [tagid]);
      //更新标签信息开始
      key = C.redisPre.tag_info;
      key = _.str.sprintf(key, tagid, 1);
      temp = yield F.redisCo.EXISTS(key);
      if (temp == 1) {
        F.redisClient.HINCRBY(key, 'pincount', 1);//标签被订阅数+1

        var pinUsers = yield redisCo.hmget(key, 'pinusers');//获取订阅用户
        pinUsers = JSON.parse(pinUsers);
        var userData = yield mysql.queryOne('SELECT face FROM mh_user WHERE uid=?', [uid]);
        pinUsers.unshift({uid: uid, face: userData['face']});
        if (pinUsers.length == 11) {
          pinUsers.splice(10, 1)
        }
        F.redisClient.HMSET(key, 'pinusers', JSON.stringify(pinUsers));//重新写标签缓存最近订阅人
      }
      //更新标签信息结束
      yield F.addDynamicInfo(loginStatus.uid, 4, tagid);
      gain = yield F.generateIntegralLog(uid, 9, tagid);//订阅成功后获得积分
    }

  } else if (act == 2 || act == 12) { // 取消订阅
    if (isPinTag.length > 0) {
      // 删除订阅
      result = yield mysql.query('DELETE FROM mh_pintag WHERE uid=? AND tagid=?', [uid, tagid]);
      if (result.affectedRows < 1) {
        return F.returnMsg(400, '失败', 1);
      }
      var pintagtimes = yield mysql.queryOne('SELECT pintagtimes FROM mh_user_info WHERE uid=?', [uid]);
      if (parseInt(pintagtimes['pintagtimes']) > 0) {
        // 订阅数减1
        mysql.query('UPDATE mh_user_info SET pintagtimes=pintagtimes-1 WHERE uid=? AND pintagtimes>0', [uid]);
        //更新订阅人信息开始
        var key = C.redisPre.user_info;
        key = _.str.sprintf(key, parseInt(uid));
        var temp = yield F.redisCo.EXISTS(key);
        if (temp == 1) {
          F.redisClient.HINCRBY(key, 'pinTags', -1);//用户发帖数-1
        }
        //更新订阅人信息结束
      }

//        if (result.affectedRows < 1) {
//          return F.returnMsg(400, '失败', 1);
//        }
      var pincount = yield mysql.queryOne('SELECT pincount FROM mh_tags WHERE tagid=?', [tagid]);
      if (parseInt(pincount['pincount']) > 0) {
        // 标签订阅数减1
        mysql.query('UPDATE mh_tags SET pincount=pincount-1 WHERE tagid=? AND pincount>0', [tagid]);
        //更新标签信息开始
        var key = C.redisPre.tag_info;
        key = _.str.sprintf(key, parseInt(tagid), 1);
        var temp = yield F.redisCo.EXISTS(key);
        if (temp == 1) {
          F.redisClient.HINCRBY(key, 'pincount', -1);//标签被订阅数-1

          var pinUsers = [];
          var tagPinData = yield mysql.query('SELECT mp.uid,mu.face FROM mh_pintag mp LEFT JOIN mh_user mu ON mp.uid=mu.uid WHERE mp.tagid=? ORDER BY mp.timeline DESC LIMIT 0,10', [parseInt(tagid)])
          if (tagPinData.length > 0) {
            pinUsers = tagPinData;
          }
          F.redisClient.HMSET(key, 'pinusers', JSON.stringify(pinUsers));//重新写标签缓存最近订阅人
        }
        //更新标签信息结束
      }
      gain = yield F.generateIntegralLog(uid, 10, tagid);//取消订阅成功后扣积分
//        if (result.affectedRows < 1) {
//          return F.returnMsg(400, '失败', 1);
//
//        }
    }
  }
  var tags = yield MTags.getTags('tagid,tagtype,tagtitle,tagimg,tagcount,pincount', 'tagid=?', [tagid]);//标签列表
  var tagurl = F.generateTagUrl(tags[0]['tagimg'], tags[0]['tagid']);

  if (loginStatus.status) {
    var pinTags = yield MTags.getPinTags("tagid", "uid=? and tagid=?", [loginStatus.uid, tags[0]['tagid']]);//查看是否订阅
    tags[0].pin = (pinTags.length != 0);
  } else {
    tags[0].pin = false;
  }
  var pinCount = tags[0].pincount + C.appendParm.pinCount;
  var data = {
    tagid: tagid,
    pin: tags[0].pin,
    tagtype: tags[0].tagtype,
    tagtitle: tags[0].tagtitle,
    tagcount: tags[0].tagcount,
    pincount: pinCount,
    tagurl: tagurl
  };
  var msg = "";
  if (act == 1) {
    msg = "订阅成功";
  } else if (act == 2) {
    msg = "取消订阅成功";
  }
  return F.returnMsg(200, {act: msg, e: gain}, 4, data);
  //return F.returnMsg(200, '取消订阅成功', 3, {tagid: tagid, pin: false});

};

/*
 @todo API22 获取动态信息列表
 */
exports.getDynamicInfo = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  //var session=Env.session;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才执行此操作', 3);
  }
  var version = fields.apiVerNum;
  var type = fields.type;//1 动态列表 2 提醒列表  3 最近关注我 4 最新回复我 【将2的列表拆分成3和4】
  var page = fields.page || 1;//当前页
  var pageSize = fields.pagesize || C.pageSize;//页大小
  var beginIndex = (page - 1) * pageSize;//开始索引
  var uid = parseInt(loginStatus.uid);//登录者id
  var limit = '';
  var condition = '';
  if (type == 1) {//动态列表
    var iidStr = 0;
    var friend = yield F.userList(uid, 2);//取得好友
    friend = friend.toString();
    //var dyData=yield mysql.query('SELECT mdi.iid FROM mh_dynamic_info mdi LEFT JOIN mh_friend mf ON mdi.authorid=mf.fuid WHERE mf.uid=? ORDER BY mdi.iid DESC LIMIT ?,?',[uid,beginIndex,pageSize]);
    var dyData = yield mysql.query('SELECT mdi.iid FROM mh_dynamic_info mdi WHERE mdi.authorid IN(' + friend + ') AND mdi.type_id!=2 AND type_id!=5 ORDER BY mdi.iid DESC LIMIT ?,?', [beginIndex, pageSize]);
    if (dyData.length > 0) {
      for (var i in dyData) {
        iidStr = iidStr == 0 ? dyData[i]['iid'] : iidStr + ',' + dyData[i]['iid'];
      }
    }
    condition = ' where (mdi.iid in(' + iidStr + '))';//动态列表条件
  } else if (type == 2 || type == 3 || type == 4) {//提醒列表
    limit = ' LIMIT ?,?';
    if (version == 1) {
      if(type == 2){ condition = ' where (mdi.uid=? AND mdi.reply=0 AND (mdi.type_id=3 or mdi.type_id=2))';}//2回帖 3关注
      if(type == 3){ condition = ' where (mdi.uid=? AND mdi.reply=0 AND mdi.type_id=3)';} //v1关注我的数据
      if(type == 4){ condition= ' where (mdi.uid=? AND mdi.reply=0 AND mdi.type_id=2)';} //v1回复我的数据
      //condition = ' where (mdi.uid=? AND mdi.reply=0 AND (mdi.type_id=3 or mdi.type_id=2))';//2回帖 3关注
    } else if (version == 2) {
      if(type == 2){ condition = ' where (mdi.uid=? AND (mdi.type_id=3 or mdi.type_id=2 or mdi.type_id=5))'; };//5 标记
      if(type == 3){ condition = ' where (mdi.uid=? AND mdi.type_id=3)'; };//v2关注我的数据
      if(type == 4){ condition = ' where (mdi.uid=? AND ( mdi.type_id=2 or mdi.type_id=5))'; };//v2回复我的数据
      //condition = ' where (mdi.uid=? AND (mdi.type_id=3 or mdi.type_id=2 or mdi.type_id=5))'; //5 标记
    }
  }

  var dynamicInfo = yield mysql.query(
    'SELECT mdi.iid,mdi.authorid uid1,mdi.type_id type,mdi.uid uid2,mdi.tid,mdi.tagid,mdi.timeline,mdi.pid,mdi.reply,ifnull(mu.nickname,"") nickname1,' +
    'ifnull(mu1.nickname,"") nickname2,ifnull(SUBSTR(mpc.post FROM 1 FOR 40),"") post,ifnull(mtag.tagtitle,"") tagtitle,ifnull(mtag.tagtype,"") tagtype,ifnull(mtag.lasttid,0) lasttid,IFNULL(mu.face,0) face1,IFNULL(mu1.face,0) face2' +
    ' FROM mh_dynamic_info mdi' +
    ' LEFT JOIN mh_user mu ON mdi.authorid=mu.uid' +
    ' LEFT JOIN mh_user mu1 ON mdi.uid=mu1.uid' +
    ' LEFT JOIN mh_thread mt ON mdi.tid=mt.tid' +
    ' LEFT JOIN mh_post_content mpc ON mt.pid=mpc.pid' +
    ' LEFT JOIN mh_tags mtag ON mdi.tagid=mtag.tagid' + condition +
    ' ORDER BY iid DESC' + limit, [uid, beginIndex, parseInt(pageSize)]
  );
  if (dynamicInfo.length > 0) {
    var userInfo = yield F.returnUserInfo(uid);
    userInfo = userInfo[0];
    var updateUserCache = {};
    if (type == 1 && dynamicInfo[0].iid != parseInt(userInfo.lastdyid) && page == 1) {//写入最后浏览动态id
      updateUserCache.lastdyid = dynamicInfo[0].iid;
      yield F.updateUserCache(uid, updateUserCache);//更新用户缓存
      mysql.query('UPDATE mh_user_info SET lastdyid=? WHERE uid=?', [dynamicInfo[0].iid, uid]);
    } else if ((type == 2 || type == 3 || type ==4 ) && dynamicInfo[0].iid != parseInt(userInfo.lastrmid) && page == 1) {//写入最后浏览消息id
      updateUserCache.lastrmid = dynamicInfo[0].iid;
      yield F.updateUserCache(uid, updateUserCache);//更新用户缓存
      mysql.query('UPDATE mh_user_info SET lastrmid=? WHERE uid=?', [dynamicInfo[0].iid, uid]);
    }
    for (var i in dynamicInfo) {
      var dynamicType = parseInt(dynamicInfo[i]['type']);
      dynamicInfo[i]['faceUrl1'] = '';
      dynamicInfo[i]['faceUrl2'] = '';
      dynamicInfo[i]['friend1Status'] = false;
      dynamicInfo[i]['friend2Status'] = false;
      dynamicInfo[i]['pinStatus'] = false;
      if (dynamicType == 1) {//发帖
        dynamicInfo[i]['type'] = 2;
        dynamicInfo[i]['faceUrl1'] = F.generateFaceUrl(dynamicInfo[i]['face1'], dynamicInfo[i]['uid1']);
        var threadData = yield mysql.queryOne('SELECT mpc.pid,ifnull(SUBSTR(mpc.post FROM 1 FOR 40),"") post,mp.imgext,mt.imagestring FROM mh_post_content mpc INNER JOIN mh_thread mt ON mpc.pid=mt.pid INNER JOIN mh_post mp ON mt.pid=mp.pid  WHERE mt.tid=?', [dynamicInfo[i]['tid']]);
        dynamicInfo[i]['post'] = '';
        dynamicInfo[i]['img'] = C.upyun.img_url + '/none.png';
        if (threadData) {
          dynamicInfo[i]['post'] = threadData['post'];
          if (threadData['imgext'] != '') {
            //dynamicInfo[i]['img'] = F.generateAttachmentUrl(threadData['pid'], threadData['imgext'], 1);
            dynamicInfo[i]['img'] = imgRule.str2imgURI(threadData['imagestring'].split(',')[0])[0].imgURI + C.upyun.suffix_min;
          }
        }
      } else if (dynamicType == 2) {// 回帖
        dynamicInfo[i]['type'] = 5;
        if (dynamicInfo[i]['reply'] != 0) {
          dynamicInfo[i]['type'] = 6;
        }
        dynamicInfo[i]['faceUrl1'] = F.generateFaceUrl(dynamicInfo[i]['face1'], dynamicInfo[i]['uid1']);
        var threadData = yield mysql.queryOne('SELECT mpc.pid,mp.imgext,mt.imagestring FROM mh_post_content mpc INNER JOIN mh_thread mt ON mpc.pid=mt.pid INNER JOIN mh_post mp ON mt.pid=mp.pid  WHERE mt.tid=?', [dynamicInfo[i]['tid']]);
        var postData = yield mysql.queryOne('SELECT ifnull(SUBSTR(post FROM 1 FOR 40),"") post FROM mh_post_content WHERE pid=?', [dynamicInfo[i]['pid']]);
        dynamicInfo[i]['post'] = '';
        dynamicInfo[i]['img'] = C.upyun.img_url + '/none.png';
        if (threadData) {
          if (threadData['imgext'] != '') {
            //dynamicInfo[i]['img'] = F.generateAttachmentUrl(threadData['pid'], threadData['imgext'], 1);
            dynamicInfo[i]['img'] = imgRule.str2imgURI(threadData['imagestring'].split(',')[0])[0].imgURI + C.upyun.suffix_min;
          }
        }
        if (postData) {
          dynamicInfo[i]['post'] = postData['post'];
        }
      } else if (dynamicType == 3) {//关注type
        dynamicInfo[i]['type'] = 1;
        if (type == 2 || type == 3) {
          dynamicInfo[i]['type'] = 4;
        }
        //以下提取我的关注人
        var friendInfo = yield mysql.query('select fuid from mh_friend WHERE uid=?', [uid]);
        var fData = [];
        if (friendInfo.length > 0) {
          for (var j in friendInfo) {
            fData[j] = friendInfo[j]['fuid'];
          }
        }
        for (var k in C.sns.manager_uid) {//把系统管理员加进去
          fData.push(C.sns.manager_uid[k]);
        }
        if (_.contains(fData, dynamicInfo[i]['uid1'])) {//第一个人是朋友
          dynamicInfo[i]['friend1Status'] = true;
          if (_.contains(fData, dynamicInfo[i]['uid2'])) {
            dynamicInfo[i]['friend2Status'] = true;
          }
          dynamicInfo[i]['faceUrl1'] = F.generateFaceUrl(dynamicInfo[i]['face1'], dynamicInfo[i]['uid1']);
          dynamicInfo[i]['faceUrl2'] = F.generateFaceUrl(dynamicInfo[i]['face2'], dynamicInfo[i]['uid2']);
        } else {
          dynamicInfo[i]['faceUrl1'] = F.generateFaceUrl(dynamicInfo[i]['face1'], dynamicInfo[i]['uid1']);
        }
      } else if (dynamicType == 4) {//订阅
        dynamicInfo[i]['type'] = 3;
        var pinTag = yield mysql.query('select tagid from mh_pintag WHERE uid=?', [uid]);
        if (pinTag.length > 0) {
          dynamicInfo[i]['pinStatus'] = true;
        }
        dynamicInfo[i]['faceUrl1'] = F.generateFaceUrl(dynamicInfo[i]['face1'], dynamicInfo[i]['uid1']);
        dynamicInfo[i]['tagurl'] = '';
        if (dynamicInfo[i]['tagtype'] == 1) {//系统标签用标签图
          var tagData = yield mysql.queryOne('SELECT tagid,tagimg FROM mh_tags WHERE tagid=?', [dynamicInfo[i]['tagid']]);
          if (tagData) {
            dynamicInfo[i]['tagurl'] = F.generateTagUrl(tagData['tagimg'], tagData['tagid'], 1);
          }
        } else {//自定义标签用该标签最后一个发帖图
          var threadData = yield mysql.queryOne('SELECT mpc.pid,mp.imgext,mt.imagestring FROM mh_post_content mpc INNER JOIN mh_thread mt ON mpc.pid=mt.pid INNER JOIN mh_post mp ON mt.pid=mp.pid  WHERE mt.tid=?', [dynamicInfo[i]['lasttid']]);
          dynamicInfo[i]['tagurl'] = C.upyun.img_url + '/none.png';
          if (threadData && threadData['imgext'] != '') {
            //dynamicInfo[i]['tagurl'] = F.generateAttachmentUrl(threadData['pid'], threadData['imgext'], 1);
            dynamicInfo[i]['tagurl'] = imgRule.str2imgURI(threadData['imagestring'].split(',')[0])[0].imgURI + C.upyun.suffix_min;
          }
        }
      } else if (dynamicType == 5) {//在帖子中标记某人
        dynamicInfo[i]['type'] = 7;
        dynamicInfo[i]['faceUrl1'] = F.generateFaceUrl(dynamicInfo[i]['face1'], dynamicInfo[i]['uid1']);
        var threadData = yield mysql.queryOne('SELECT mpc.pid,mpc.post,mp.imgext,mt.imagestring FROM mh_post_content mpc INNER JOIN mh_thread mt ON mpc.pid=mt.pid INNER JOIN mh_post mp ON mt.pid=mp.pid  WHERE mt.tid=?', [dynamicInfo[i]['tid']]);
        dynamicInfo[i]['post'] = '';
        dynamicInfo[i]['img'] = C.upyun.img_url + '/none.png';
        if (threadData) {
          if (threadData['imgext'] != '') {
            //dynamicInfo[i]['img'] = F.generateAttachmentUrl(threadData['pid'], threadData['imgext'], 1);
            dynamicInfo[i]['img'] = imgRule.str2imgURI(threadData['imagestring'].split(',')[0])[0].imgURI + C.upyun.suffix_min;
          }
          dynamicInfo[i]['post'] = threadData['post'];
        }
      }
      var userInfo = yield F.returnUserInfo(dynamicInfo[i]['uid1']);
      userInfo = userInfo[0];
      var level = F.getLevelfromIntegral(parseInt(userInfo.integral));
      dynamicInfo[i].level = level.lid;
      dynamicInfo[i].vip = parseInt(userInfo.vip);
      //显示达人称号
      //显示达人等级
      if (parseInt(userInfo.talentid) > 0 && parseInt(userInfo.vip) == 0) {// 是否达人  (VIP 无达人属性)
        dynamicInfo[i].talent = F.getTalentInfo(parseInt(userInfo.talentid)).name;
        dynamicInfo[i].talent_level = level.talent_level; //  this.getTalentInfo(threads
      } else {
        dynamicInfo[i].talent = '';
        dynamicInfo[i].talentid = 0
      }
      //delete dynamicInfo[i]['iid'];
      delete dynamicInfo[i]['face1'];
      delete dynamicInfo[i]['face2'];

      switch (parseInt(dynamicInfo[i]['type'])) {
        case 1:
          delete dynamicInfo[i].tid;
          delete dynamicInfo[i].tagid;
          delete dynamicInfo[i].post;
          delete dynamicInfo[i].tagtitle;
          delete dynamicInfo[i].tagtype;
//          delete dynamicInfo[i].faceUrl1;
          delete dynamicInfo[i].friend1Status;
          delete dynamicInfo[i].pinStatus;
          delete dynamicInfo[i].pid;
          delete dynamicInfo[i].reply;
          delete dynamicInfo[i].lasttid;
          break;
        case 2:
          delete dynamicInfo[i].uid2;
          delete dynamicInfo[i].tagid;
          delete dynamicInfo[i].nickname2;
          delete dynamicInfo[i].tagtitle;
          delete dynamicInfo[i].tagtype;
//          delete dynamicInfo[i].faceUrl1;
          delete dynamicInfo[i].faceUrl2;
          delete dynamicInfo[i].friend1Status;
          delete dynamicInfo[i].friend2Status;
          delete dynamicInfo[i].pinStatus;
          delete dynamicInfo[i].pid;
          delete dynamicInfo[i].reply;
          delete dynamicInfo[i].lasttid;
          break;
        case 3:
          delete dynamicInfo[i].uid2;
          delete dynamicInfo[i].tid;
          delete dynamicInfo[i].nickname2;
          delete dynamicInfo[i].post;
//          delete dynamicInfo[i].faceUrl1;
          delete dynamicInfo[i].faceUrl2;
          delete dynamicInfo[i].friend1Status;
          delete dynamicInfo[i].friend2Status;
          delete dynamicInfo[i].pid;
          delete dynamicInfo[i].reply;
          delete dynamicInfo[i].lasttid;
          break;
        case 4:
          delete dynamicInfo[i].uid2;
          delete dynamicInfo[i].tid;
          delete dynamicInfo[i].tagid;
          delete dynamicInfo[i].nickname2;
          delete dynamicInfo[i].post;
          delete dynamicInfo[i].tagtitle;
          delete dynamicInfo[i].tagtype;
          delete dynamicInfo[i].faceUrl2;
          delete dynamicInfo[i].friend2Status;
          delete dynamicInfo[i].pinStatus;
          delete dynamicInfo[i].pid;
          delete dynamicInfo[i].reply;
          delete dynamicInfo[i].lasttid;
          break;
        case 5:
        case 6:
        case 7:
          delete dynamicInfo[i].uid2;
          delete dynamicInfo[i].tagid;
          delete dynamicInfo[i].nickname2;
          delete dynamicInfo[i].tagtitle;
          delete dynamicInfo[i].tagtype;
//          delete dynamicInfo[i].faceUrl1;
          delete dynamicInfo[i].faceUrl2;
          delete dynamicInfo[i].friend1Status;
          delete dynamicInfo[i].friend2Status;
          delete dynamicInfo[i].pinStatus;
          delete dynamicInfo[i].pid;
          delete dynamicInfo[i].reply;
          delete dynamicInfo[i].lasttid;
          break;
        default:
          break;
      }
    }
    var newestiid = 0;
    if (type == 1) {
      newestiid = parseInt(userInfo.lastdyid);
    } else if (type == 2 || type == 3 || type == 4) {
      newestiid = parseInt(userInfo.lastrmid);
    }
    return F.returnMsg(200, '列表返回成功', 3, {pageIndex: page, newestiid: newestiid, items: dynamicInfo});
  } else {
    return F.returnMsg(300, '已没有数据了', 3);
  }
};

/*
 * @todo API23 关注及粉丝列表
 * */
exports.getFriendList = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var act = fields.act;
  var uid = fields.uid;
  var simple = fields.simple;//当simple=1时只返回uid和nickname字段，在帖子添加人标签时使用
  var page = fields.page || 1;
  var pageSize = fields.pagesize || C.pageSize;
  var beginIndex = (page - 1) * pageSize;

  // 判断用户是否存在
  var isUserExist = yield MUsers.getUser('uid', 'uid=?', [uid]);
  if (isUserExist.length == 0) {
    return F.returnMsg(400, '用户不存在', 1);
  }

  var returnData = {
    pageIndex: page,
    items: []
  };
  if (act == 1 || act == 11) {  // 关注列表
    // 查找我关注的人ID
    var friendIds = yield mysql.query('SELECT fuid FROM mh_friend WHERE uid=? order by timeline desc LIMIT ?,?', [uid, beginIndex, parseInt(pageSize)]);
    if (page == 1) { // 如果是第一页，则添加发言人账号
      for (var i in C.sns.manager_uid) {
        friendIds.unshift({fuid: C.sns.manager_uid[i]})
      }
    }
    if (friendIds.length <= 0) {
      return F.returnMsg(300, '已没有数据了', 3);
    }
    // 查找关注的人信息
    for (var i in friendIds) {
      var friendUid = friendIds[i].fuid;
      var friendData = yield mysql.queryOne('SELECT u.uid,u.nickname,u.face,u.vip,ui.signature,ui.integral,ui.talentid FROM mh_user u LEFT JOIN mh_user_info ui ON u.uid=ui.uid WHERE u.uid=?', [friendUid]);
      if (!friendData) {
        continue;
      }
      friendData.faceUrl = F.generateFaceUrl(friendData.face, friendUid);

      if (_.v.isIn(friendUid, C.sns.manager_uid)) { //判断是否系统发言用户
        friendData.friendStatus = true;
      } else { // 不是系统发言用户
        if (loginStatus.status) {
          // 判断自己于关注人的好友关系
          var isFriend = yield MUsers.isFriend(loginStatus.uid, friendUid);
          if (isFriend) {
            friendData.friendStatus = true;
          } else {
            friendData.friendStatus = false;
          }
        } else {
          friendData.friendStatus = false;
        }
      }
      friendData.level = F.getLevelfromIntegral(friendData.integral).lid;


      var level = F.getLevelfromIntegral(friendData.integral);
      friendData.level = level.lid;


      //显示达人称号
      //显示达人等级
      if (friendData.talentid > 0 && friendData.vip == 0) {// 是否达人  (VIP 无达人属性)
        friendData.talent = F.getTalentInfo(friendData.talentid).name;
        friendData.talent_level = level.talent_level; //  this.getTalentInfo(threads
      } else {
        friendData.talent = '';
        friendData.talentid = 0
      }


      delete friendData.face;
      delete friendData.integral;
      delete friendData.talentid;
      if (simple && simple == 1) {//act=1且simple=1时只返回uid和nickname（用于发帖选择用户作为标签）
        delete friendData.signature;
        delete friendData.faceUrl;
        delete friendData.friendStatus;
      }
      returnData.items.splice(returnData.items.length, 0, friendData);
    }
    return F.returnMsg(200, '列表返回成功', 3, returnData);
  } else if (act == 2 || act == 12) {  // 粉丝列表
    // 查找粉丝ID
    var fanIds = yield mysql.query('SELECT uid FROM mh_friend WHERE fuid=? order by timeline desc LIMIT ?,?', [uid, beginIndex, parseInt(pageSize)]);
    if (fanIds.length <= 0) {
      return F.returnMsg(300, '已没有数据了', 3);
    }

    // 查找粉丝信息
    for (var i in fanIds) {
      var fanUid = fanIds[i].uid;
      // 粉丝详细信息
      var fanData = yield mysql.queryOne('SELECT u.uid,u.nickname,u.face,u.vip,ui.signature,ui.integral,ui.talentid FROM mh_user u LEFT JOIN mh_user_info ui ON u.uid=ui.uid WHERE u.uid=?', [fanUid]);
      if (!fanData) {
        continue;
      }
      // 获取粉丝头像url
      fanData.faceUrl = F.generateFaceUrl(fanData.face, fanUid);
      if (loginStatus.status) {
        // 判断自己去粉丝的好友关系
        var isFriend = yield MUsers.isFriend(loginStatus.uid, fanUid);
        if (isFriend) {
          fanData.friendStatus = true;
        } else {
          fanData.friendStatus = false;
        }
      } else {  // 未登录好友状态都为false
        fanData.friendStatus = false;
      }
      var level = F.getLevelfromIntegral(fanData.integral);
      fanData.level = level.lid;


      //显示达人称号
      //显示达人等级
      if (fanData.talentid > 0 && fanData.vip == 0) {// 是否达人  (VIP 无达人属性)
        fanData.talent = F.getTalentInfo(fanData.talentid).name;
        fanData.talent_level = level.talent_level; //  this.getTalentInfo(threads
      } else {
        fanData.talent = '';
        fanData.talentid = 0
      }


      delete fanData.face;
      delete fanData.integral;
      delete fanData.talentid;
      returnData.items.splice(returnData.items.length, 0, fanData);
    }

    return F.returnMsg(200, '列表返回成功', 3, returnData);
  } else {
    return F.returnMsg(400, '参数错误，无数据', 3);
  }
};
/*
 @todo API25.	友盟device_token捆绑
 */
exports.bindUmeng = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '用户鉴权失败', 3);
  }

  var osType = fields.type;
  var device_token = fields.device_token;
  var channelid = fields.channelid;
  var appver = fields.appver;
  var register = fields.register;
  var setData = [];
  var result;
  var flag;
  let device_id = fields['device_id']['device_id'] || '';
  let device_id_type = fields['device_id']['type'] || 0;
  let tokenkey = fields.tokenkey || '';
  if (channelid) {
    setData.push('channelid=' + channelid);
  } else {
    channelid = '';
  }
  if (appver) {
    setData.push('appver=' + appver);
  } else {
    appver = '';
  }

  if (osType && device_token && osType == 1 && device_token.length == 44) {//android设备44位
    flag = yield MUsers.editUser('os_type=?,device_token=?', 'uid=?', [osType, device_token, loginStatus.uid]);
  } else if (osType && device_token && osType == 2 && device_token.length == 64) {//ios设备64位
    flag = yield MUsers.editUser('os_type=?,device_token=?', 'uid=?', [osType, device_token, loginStatus.uid]);
  }
  if (setData.length > 0) {
    console.log(device_id);
    result = yield mysql.query('insert into mh_user_log(uid,ip,os_type,devicetoken,channelid,appver,timeline,device_id,device_id_type,tokenkey) values(?,?,?,?,?,?,UNIX_TIMESTAMP(),?,?,?)',
      [loginStatus.uid, Env.ip, osType, device_token, channelid, appver, device_id, device_id_type, tokenkey]);
  }
  if (channelid != '') {//注册后记录渠道来源
    result = yield mysql.queryOne('select channelid from mh_user_info where uid=?', [loginStatus.uid]);
    if (result['channelid'] == '') { //如果未设置渠道，则当做原始渠道
      result = yield mysql.query('UPDATE mh_user_info SET channelid=? WHERE uid=?', [channelid, loginStatus.uid]);
    }
  }

  if (flag && result) {
    return F.returnMsg(200, '绑定成功', 3);
  }
  return F.returnMsg(400, '绑定失败', 3);
};


/*
 @todo 26	推送开关设置
 */
exports.settingPush = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var act = fields.act;
  var pushfriend = fields.pushfriend;
  var pushpost = fields.pushpost;
  var pushlike = fields.pushlike;
  var pushdisturb = fields.pushdisturb;


  if (!loginStatus.status) {
    return F.returnMsg(401, '用户鉴权失败', 3);
  }
  var uid = loginStatus.uid;

  if (act == 1) {
  } else if (act == 2) {
    var setData = [];
    if (pushfriend && (pushfriend == 0 || pushfriend == 1)) {
      setData.push('pushfriend=' + pushfriend);
    }
    if (pushpost && (pushpost == 0 || pushpost == 1)) {
      setData.push('pushpost=' + pushpost);
    }
    if (pushlike && (pushlike == 0 || pushlike == 1)) {
      setData.push('pushlike=' + pushlike);
    }
    if (pushdisturb && (pushdisturb == 0 || pushdisturb == 1)) {
      setData.push('pushdisturb=' + pushdisturb);
    }
    if (setData.length > 0) {
      let result = yield mysql.query('UPDATE mh_user_info SET ' + setData.join(',') + ' WHERE uid=?', uid);
      if (result.affectedRows < 1) {
        return F.returnMsg('400', '设置失败', 1);
      }
    } else {
      return F.returnMsg('400', '参数错误', 3);
    }
  }

  let result = yield mysql.queryOne('select pushfriend,pushpost,pushlike,pushdisturb from mh_user_info WHERE uid=?', uid);
  if (result) {
    return F.returnMsg(200, '成功', 3, {
      pushfriend: result.pushfriend,
      pushpost: result.pushpost,
      pushlike: result.pushlike,
      pushdisturb: result.pushdisturb
    });
  } else {
    return F.returnMsg('400', '此次操作失败', 1);
  }
};

/*
 @todo 27	获取版本升级信息
 */
exports.appUpdate = function*(Env) {
  var fields = Env.I;
  var act = fields.act;
  var osType = parseInt(fields.type);//1 Android设备, 2 IOS设备 3 android 启动页 4 ios 启动页
  var code = fields.code || 0;//当前版本号
  var channelId = fields.channelid;//渠道号，如xiaomi,yueni

  if (act == 1 && (osType == 1 || osType == 2)) { // 获取版本信息
    var result = yield mysql.queryOne('select os_type,version,code,url,note from mh_app_update where status=1 AND os_type=? order by appid desc limit 1', [osType]);
    if (result) {
      var data = {
        version: result['version'],
        code: result['code'],
        note: result['note']
      };
      if (osType == 1) {
        data.url = C.appUpdate_url_1;
        return F.returnMsg(200, '成功', 3, {Android: data});
      } else if (osType == 2) {
        data.url = C.appUpdate_url_2;
        return F.returnMsg(200, '成功', 3, {IOS: data});
      }
    }
    return F.returnMsg('300', '没有可用的更新', 3);
  } else if (act == 2 && (osType == 1 || osType == 2)) {  //获取启动页信息
    switch (osType) {
      case 1:
        osType = 3;
        break;
      case 2:
        osType = 4;
        break;
      default:
        break;
    }
    /*获取客户端的CPU类型并存入数据库
    * */
    let cpuabi = fields.cpuabi || '';
    if (!_.isEmpty(cpuabi)) {
      yield mysql.query('INSERT INTO mh_cpu_logs(cpuabi,timeline) VALUES(?,UNIX_TIMESTAMP())', [cpuabi]);
    }

    var result = yield mysql.queryOne('select appid,code from mh_app_update where status=1 AND os_type=? order by appid desc limit 1', [osType]);
    if (result) {
      var splashscreenUrl = F.generateSplashscreenUrl(result.appid);
      var data = {
        code: result['code'],
        splashscreenurl: splashscreenUrl
      };
      if (osType == 3) {
        return F.returnMsg(200, '成功', 3, {Android: data});
      } else if (osType == 4) {
        return F.returnMsg(200, '成功', 3, {IOS: data});
      }
    }
    return F.returnMsg('300', '没有可用的启动页', 3);
  } else if (act == 3 && (osType == 1 || osType == 2)) {  //获取配置信息
    var _o2oServiceApi = require('./o2oServiceApi');
    var o2oServiceApi = new _o2oServiceApi;
    let dbConfigData = yield o2oServiceApi.post('appConfig', 'detail', 1, {act: 1});
    let configData = C.appConfig;
    configData.H5_model = dbConfigData['result']['H5_model'];
    if (osType == 1) {
      return F.returnMsg(200, '成功', 3, {Android: configData});
    } else if (osType == 2) {
      return F.returnMsg(200, '成功', 3, {IOS: configData});
    }
  }
  return F.returnMsg('400', '参数错误', 1);
};

/**
 * @todo API33 获取用户列表(暂时不用)
 * @param Env
 */
exports.usersList = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '请先登录', 3);
  }
  var keyword = fields.keyword || '';
  if (keyword != '') {
    var users = yield mysql.query('SELECT uid,nickname FROM mh_user WHERE nickname like CONCAT("%",?,"%")', [keyword]);
  } else {
    var users = yield mysql.query('SELECT uid,nickname FROM mh_user');
  }
  if (users.length > 0) {
    return F.returnMsg(200, '成功', 3, {items: users});
  } else {
    return F.returnMsg(300, '已没有数据了', 3);
  }
};

/**
 * @todo API34 社会化登录
 * @param Env
 */
exports.doOauthLogin = function*(Env) {
  var fields = Env.I;
  var mediaType = fields.mediatype.toString();//媒介类型 1 QQ 2 微信
  var accessToken = fields.accesstoken;//接口调用凭证
  var openId = fields.openid;//app唯一识别码
  var expiresIn = fields.expires_in || 0;//过期时间(秒)
  if (!_.v.isIn(parseInt(mediaType), [1, 2, 4])) {
    return F.returnMsg(400, '传递的媒体参数错误', 1);
  }
  var mediaUserData = yield F.oauthLogin(mediaType, accessToken, openId);//尝试取得用户信息，成功说明传过来的票据正确。
  mediaUserData = JSON.parse(mediaUserData);
  switch (mediaType) {
    case "1"://QQ
      if (mediaUserData.ret != 0) {//非0表示拿不到信息
        return F.returnMsg(300, '授权失败', 3);
      }
      break;
    case "2":
    case "4"://微信
      if (mediaUserData.errcode != undefined && mediaUserData.errcode == 40003) {//微信返回状态码 40003代表失败
        return F.returnMsg(300, '授权失败', 3);
      }
      break;
    default:
      return F.returnMsg(400, '传递的参数错误', 1);
      break;
  }
  var userData = yield mysql.query('SELECT mut.*,mu.groupid,mu.nickname,face,mobile,IFNULL(`password`,\'\')!=\'\' as hasPassword FROM mh_users_token mut INNER JOIN mh_user mu ON mut.uid=mu.uid WHERE mut.mediatype=? AND mut.openid=? and mut.status=1', [mediaType, openId]);
  var do_login = 0;
  if (userData.length > 0) {//存在数据则直接登录
    do_login = 1;
  } else {//不存在则生成票据等数据
    var ticket = uid2(32);
    var faceUrl = '';
    var gender = 2;//预设性别为女
    var unionid = '';//用户统一标识
    switch (mediaType) {//取得第三方应用头像
      case "1"://QQ
        faceUrl = mediaUserData.figureurl_qq_2;//QQ头像 100*100
        if (mediaUserData.gender == '男') {//QQ返回gender，没有的时候默认为男
          gender = 1;
        } else {
          gender = 2;
        }
        break;
      case "2"://悦你微信
        faceUrl = mediaUserData.headimgurl;//微信头像
        gender = mediaUserData.sex;//微信返回sex 1为男 2为女
        unionid = mediaUserData.unionid;
        break;
      case "4"://瓷肌微信
        faceUrl = mediaUserData.headimgurl;//微信头像
        gender = mediaUserData.sex;//微信返回sex 1为男 2为女
        unionid = mediaUserData.unionid;
        var userData = yield mysql.query('SELECT mut.*,mu.groupid,mu.nickname,face,mobile,IFNULL(`password`,\'\')!=\'\' as hasPassword FROM mh_users_token mut INNER JOIN mh_user mu ON mut.uid=mu.uid WHERE mut.mediatype=? AND unionid=?', [2, unionid]);
        if (userData.length > 0) {//在悦你已经注册
          let yueNi_uid = parseInt(userData[0]['uid']);
          expiresIn = F.timestamp() + parseInt(expiresIn);
          let flag = yield mysql.query('INSERT INTO mh_users_token(uid,mediatype,openid,timeline,access_token,expires_in,unionid,media_data) VALUES(?,?,?,UNIX_TIMESTAMP(),?,?,?,?)', [yueNi_uid, 4, openId, accessToken, expiresIn, unionid, JSON.stringify(mediaUserData)]);
          do_login = 1;
        }
        break;
    }
    if (do_login != 1) {
      F.redisClient.hmset('reg:ticket_' + ticket, 'ticket', ticket, 'mediatype', mediaType, 'openid', openId, 'accesstoken', accessToken, 'gender', gender, 'expires_in', expiresIn, 'unionid', unionid, 'media_data', JSON.stringify(mediaUserData));//保存会话
      F.redisClient.expire('reg:ticket_' + ticket, C.user.regExp);
      return F.returnMsg(200, '生成票据成功', 3, {
        statuscode: 2,
        ticket: ticket,
        nickname: mediaUserData.nickname,
        face: faceUrl
      });
    }
  }
  if (do_login == 1) {
    // 记录登录日志
    let region_data = yield F.getUserCityData(Env.ip);
    F.loginLog(userData[0]['uid'], 1, Env.ip, region_data);
    var newTokenkey = uid2(40);
    if (F.isManager(userData[0]['groupid'])) {
      F.redisClient.hmset('siss:user:uid_' + userData[0]['uid'], 'uid', userData[0]['uid'], 'groupid', userData[0]['groupid'], 'nickname', userData[0]['nickname'], 'vestuid', userData[0]['uid'], 'vestnickname', userData[0]['nickname']);//保存会话
    } else {
      F.redisClient.hmset('siss:user:uid_' + userData[0]['uid'], 'uid', userData[0]['uid'], 'groupid', userData[0]['groupid'], 'nickname', userData[0]['nickname']);//保存会话
    }
    F.redisClient.expire('siss:user:uid_' + userData[0]['uid'], C.session.ttl);
    F.redisClient.SETEX('siss:user:token_' + newTokenkey, C.session.ttl, userData[0]['uid']);
    // 40位tokenkey
    yield MUsers.updateToken(userData[0]['uid'], newTokenkey);
    var face = F.generateFaceUrl(userData[0]['face'], userData[0]['uid'], 1);
    var minFace = F.generateFaceUrl(userData[0]['face'], userData[0]['uid']);
    return F.returnMsg(200, '登录成功', 3,
      {
        statuscode: 1,
        uid: userData[0]['uid'],
        nickname: userData[0]['nickname'],
        face: face,
        minface: minFace,
        tokenkey: newTokenkey,
        mobile: userData[0]['mobile'] || 0,
        hasPassword: userData[0]['hasPassword']
      });
  }
};

/**
 * @todo API35 头像上传成功后的Callback
 * @param Env
 */
exports.faceCallback = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能修改头像', 3);
  }
  var act = fields.act;
  var uid = fields.uid;
  var manager = fields.manager;
  if (uid && uid != loginStatus.uid && manager != 1 && !F.isManager(loginStatus.groupid, [1, 2])) {
    return F.returnMsg(400, '权限验证失败', 1);
  }
  uid = uid ? uid : loginStatus.uid;
  if (act == 1) {//act=1 头像已经上传成功
    var userData = yield mysql.query('SELECT uid FROM mh_user WHERE uid=?', [uid]);
    if (userData.length == 0) {
      return F.returnMsg(300, '用户不存在', 1);
    }
    mysql.query('update mh_user SET face=0 where uid=?', [uid]);
    var updateUserCache = {};
    updateUserCache.face = 0;
    yield F.updateUserCache(parseInt(uid), updateUserCache);//更新用户缓存
    var face = F.generateFaceUrl(0, uid, 1);
    var minFace = F.generateFaceUrl(0, uid);
    //let upyun_purge = thunkify(F.upyun.purge);
    //yield upyun_purge([face,minFace]);
    //yield F.upyun_purge([face,minFace]);
    F.upyun.purge([face, minFace], function () {
    });//强制刷新又拍云图片
    return F.returnMsg(200, '成功', 3, {face: face, minface: minFace});
  }
};

/**
 * @todo API36 意见反馈
 * @param Env
 */
exports.suggest = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能反馈信息', 3);
  }
  var act = fields.act;
  var feedback = fields.feedback;
  if (feedback == '' || feedback == undefined) {
    return F.returnMsg(400, '反馈内容不能为空', 1);
  }
  var toMail = C.email.to;//接收邮箱
  var subject = '意见反馈';
  var body = loginStatus.nickname + '(用户id为' + loginStatus.uid + ')在瓷肌中反馈了意见：' + feedback;
  yield F.sendEmail(toMail, subject, body);
  mysql.query('INSERT INTO mh_feedback(uid,feedback,timeline) VALUES(?,?,UNIX_TIMESTAMP())', [loginStatus.uid, feedback]);
  return F.returnMsg(200, '提交成功，谢谢你的意见', 1);
};

/**
 * @todo API39 获取用户
 * @param Env
 */
exports.getUsers = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var act = fields.act;
  var keyword = fields.keyword || '';
  var findFields = [];
  var findVal = [];
  findFields.push('1=1');
  var users = [];
  if (act == 1) {//在所有用户中检索
    if (keyword) {
      findFields.push('nickname like CONCAT("%",?,"%")');
      findVal.push(keyword);
      users = yield mysql.query('SELECT uid,nickname FROM mh_user WHERE ' + findFields.join(' AND ') + ' ORDER BY LENGTH(nickname),CONVERT(nickname USING gbk ) COLLATE gbk_chinese_ci ASC LIMIT 0,50', findVal);
    }
  } else if (act == 2) {//在好友加粉丝列表中检索
    if (!loginStatus.status) {
      return F.returnMsg(401, '登录用户才能操作', 3);
    }
    //var page = fields.page || 1;
    //var pageSize = fields.pagesize || C.pageSize;
    //var beginIndex = (page - 1) * pageSize;
    findVal.push(loginStatus.uid);
    findVal.push(loginStatus.uid);
    if (keyword) {
      findFields.push('nickname LIKE CONCAT("%",?,"%")');
      findVal.push(keyword);
    }
    //findVal.push(beginIndex);
    //findVal.push(pageSize);
    var tempArr = ['SELECT ' + loginStatus.uid];
    var unionAdd = '';
    for (var i in C.sns.manager_uid) {
      tempArr.push('SELECT ' + C.sns.manager_uid[i]);
    }
    if (tempArr.length != 0) {
      unionAdd += 'UNION ' + tempArr.join(' UNION ');
    }
    users = yield mysql.query('SELECT mu.uid,mu.nickname,mu.face FROM mh_user mu INNER JOIN (SELECT fuid FROM mh_friend WHERE uid=? UNION SELECT uid FROM mh_friend WHERE fuid=? ' + unionAdd + ') unu ON mu.uid=unu.fuid WHERE ' + findFields.join(' AND ') + ' ORDER BY CONVERT(nickname USING gbk ) COLLATE gbk_chinese_ci ASC', findVal);
    for (var i in users) {
      users[i].faceUrl = F.generateFaceUrl(users[i].face, users[i].uid);
      delete users[i].face;
    }
  }

  if (users.length > 0) {
    return F.returnMsg(200, '获取成功', 3, {users: users});
  } else {
    return F.returnMsg(300, '获取失败', 3);
  }
};

/**
 * @todo API41.    动态、通知、消息未读数目
 * @param Env
 */
exports.getUnread = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var dynamic = 0;//未读动态数
  var notification = 0;//未读通知数
  var remind = 0;//未读提醒数
  var focus =0;//未读提醒数中关注我的
  var reply =0;//未读提醒数中回复我的
  if (loginStatus.status) {
    var uid = parseInt(loginStatus.uid);
    var userInfo = yield F.returnUserInfo(uid);
    userInfo = userInfo[0];
    var lastdyid = parseInt(userInfo.lastdyid);//最后浏览动态id
    var dynamicD = yield mysql.queryOne('SELECT COUNT(mdi.iid) count FROM mh_dynamic_info mdi LEFT JOIN mh_friend mf ON mdi.authorid=mf.fuid WHERE mdi.iid>? AND mf.uid=? AND mdi.type_id!=2 AND type_id!=5', [lastdyid, uid]);
    dynamic = dynamicD.count;

    var lastrmid = parseInt(userInfo.lastrmid);//最后浏览提醒id
    var remindD = yield mysql.queryOne('SELECT COUNT(mdi.iid) count FROM mh_dynamic_info mdi WHERE mdi.iid>? AND mdi.uid=? AND (mdi.type_id=3 or mdi.type_id=2 or mdi.type_id=5)', [lastrmid, uid]);
    remind = remindD.count;

    //最后浏览提醒中的回复我的
    var replyD = yield mysql.queryOne('SELECT COUNT(mdi.iid) count FROM mh_dynamic_info mdi WHERE mdi.iid>? AND mdi.uid=? AND ( mdi.type_id=2 or mdi.type_id=5)', [lastrmid, uid]);
    reply = replyD.count;

    //最后浏览提醒中的关注我的我的
    var focusD = yield mysql.queryOne('SELECT COUNT(mdi.iid) count FROM mh_dynamic_info mdi WHERE mdi.iid>? AND mdi.uid=? AND mdi.type_id=3', [lastrmid, uid]);
    focus = focusD.count;


    var lastnfid = parseInt(userInfo.lastnfid);//最后浏览通知id
    var notificationD = yield mysql.queryOne('SELECT COUNT(ms.aid) count FROM mh_slider ms WHERE ms.`status`=1 AND UNIX_TIMESTAMP() BETWEEN ms.begintime AND ms.endtime AND ms.sstype=4 AND aid>?', [lastnfid]);
    notification = notificationD.count;
  }
  return F.returnMsg(200, '获取成功', 3, {
    loginStatus: fields.loginStatus.status ? 1 : 0,
    dynamic: dynamic,
    notification: notification,
    remind: remind,
    reply:reply,
    focus:focus
  });
};


/**
 * @todo API42.    签到
 * @param Env
 *  act=1 签到
 *  act=2 判断当天是否已签到
 */
exports.signin = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var act = fields.act;

  if (loginStatus.status) {
    var uid = parseInt(loginStatus.uid);
    var userInfo = yield F.returnUserInfo(uid);
    var timestamp = F.timestamp();
    //var signinInfo=yield mysql.queryOne('SELECT  mui.signtimes,mui.lastsigntime FROM mh_user_info mui WHERE mui.uid = ?',[uid]);

    // 计算到当天的间隔天数
    var days = F.dateDiff(userInfo[0]['lastsigntime']);
    if (act == 1) { // 签到
      if (days == 1) {// 判断是连续签到
        mysql.queryOne('UPDATE mh_user_info mui SET mui.signtimes=mui.signtimes+1, mui.lastsigntime = ? WHERE mui.uid = ?', [timestamp, uid],
          function (error, rows, fields) {
            if (error) {
              console.log('[ERROR] 签到出错 ' + error);
            }
          });
        var gain = yield F.generateIntegralLog(uid, 2); // 2 签到
        //签到缓存处理
        yield F.updateUserCache(uid, {lastsigntime: timestamp, signtimes: parseInt(userInfo[0].signtimes) + 1});
        return F.returnMsg(200, '签到成功', 3, {experience: gain, days: days + 1});
      } else if (days == 0) { // 当天已经签到
        return F.returnMsg(400, '每天只能签到一次！', 1);
      } else { // 不是连续签到
        mysql.queryOne('UPDATE mh_user_info mui SET mui.signtimes=0, mui.lastsigntime=UNIX_TIMESTAMP() WHERE mui.uid = ?', [uid],
          function (error, rows, fields) {
            if (error) {
              console.log('[ERROR] 签到出错 ' + error);
            }
          });
        var gain = yield F.generateIntegralLog(uid, 2); // 2 签到
        yield F.updateUserCache(uid, {lastsigntime: timestamp, signtimes: 1});
        return F.returnMsg(200, '签到成功', 3, {experience: gain, days: 1});
      }
    } else if (act == 2) { // 查询是否已签到
      if (days == 0) { //
        return F.returnMsg(200, '已签到', 3, {signin: true});
      } else {
        return F.returnMsg(200, '未签到', 3, {signin: false});
      }
    }

  } else {
    return F.returnMsg(401, '登录用户才能操作', 3);
  }
};


/**
 * @todo API43.    更新地理位置
 * @param Env
 *  act=1 更新地理位置
 */
exports.updateGeo = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var act = fields.act;
  var geoLat = fields.geoLat;
  var geoLng = fields.geoLng;

  if (loginStatus.status) {
    if (_.v.isFloat(geoLat) && _.v.isFloat(geoLng)) {
      var uid = parseInt(loginStatus.uid);
      mysql.query('INSERT INTO mh_user_geo_log(uid,geoLat,geoLng,timeline) VALUES(?,?,?,UNIX_TIMESTAMP())', [uid, geoLat, geoLng],
        function (error, rows, fields) {
          if (error) {
            console.log('[ERROR] 更新地理位置 ' + error);
          }
        });
      var userGeo = {};
      userGeo.uid = uid;
      userGeo.longitude = geoLat;
      userGeo.longitude = geoLng;
      F.saveUser2Mongo(userGeo);//更新用户地理位置信息
      return F.returnMsg(200, '成功', 3);
    } else {
      return F.returnMsg(400, '参数错误', 3);
    }
  } else {
    return F.returnMsg(200, '登录用户才能操作', 3);
  }
};

/**
 * @todo API44.    获取用户今日任务
 * @param Env
 *  act=1 更新地理位置
 */
exports.getTask = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能操作', 3);
  }
  var returnTask = [];
  var uid = parseInt(loginStatus.uid);
  var levelList = C.level_list;
  var levelListAdd = C.level_list_add;
  var levelActionText = C.level_action_text;
  var levelActionUnit = C.level_action_unit;
  var totalIntegral = 0;
  var integralDetail = yield  mysql.query("SELECT optype,SUM(gain) total,COUNT(integralid) count FROM mh_integral_log WHERE uid=? AND timeline BETWEEN UNIX_TIMESTAMP(DATE_FORMAT(NOW(),'%Y-%m-%d')) AND UNIX_TIMESTAMP(DATE_ADD(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 1 DAY)) GROUP BY optype", [uid]);
  if (levelList && levelList.length > 0) {//固定项目数据
    var userInfo = yield F.returnUserInfo(uid);
    var levelData = F.getLevelfromIntegral(parseInt(userInfo[0].integral));
    var gainArr = levelData.reward;
    var sign = F.dateDiff(userInfo[0].lastsigntime);
    for (var i in levelList) {
      var count = 0;
      var gain = 0;
      for (var j in integralDetail) {
        if (levelList[i] == integralDetail[j].optype) {
          count = integralDetail[j].count;
          gain = integralDetail[j].total;
          break;
        }
      }
      var detail = '';
      if (levelList[i] == 2) {//签到
        var temp = levelActionUnit[levelList[i]].split('/');
        if (sign == 0) {//已签到
          count = 1;
          detail = temp[1];
        } else {//未签到
          detail = temp[0];
        }
      } else {
        detail = count + levelActionUnit[levelList[i]];
      }
      totalIntegral += gain;
      if (gain == 0) {
        gain = gainArr[levelList[i]];
      }
      gain = gain > 0 ? '+' + gain : gain;
      returnTask.push({"title": levelActionText[levelList[i]], "detail": detail, "count": count, gain: gain});
    }
  }
  if (levelListAdd && levelListAdd.length > 0) {//动态添加数据
    var contentShareCount = 0;
    var contentShareGain = 0;
    for (var i in levelListAdd) {
      var count = 0;
      var gain = 0;
      for (var j in integralDetail) {
        if (levelListAdd[i] == integralDetail[j].optype) {
          count = integralDetail[j].count;
          gain = integralDetail[j].total;
          break;
        }
      }
      if (count == 0) continue;
      if (levelListAdd[i] == 19 || levelListAdd[i] == 20) {//19将帖子分享给好友，20将标签分享给好友
        contentShareCount += count;
        contentShareGain += gain;
        continue;
      }
      var detail = '';
      detail = count + levelActionUnit[levelListAdd[i]];
      totalIntegral += gain;
      if (gain == 0) {
        gain = gainArr[levelListAdd[i]];
      }
      gain = gain > 0 ? '+' + gain : gain;
      returnTask.push({"title": levelActionText[levelListAdd[i]], "detail": detail, "count": count, gain: gain});
    }
    if (contentShareCount > 0) {//合并分享帖子和分享标签
      returnTask.push({
        "title": '将内容分享给好友',
        "detail": contentShareCount + '次',
        "count": contentShareCount,
        gain: '+' + contentShareGain
      });
    }
  }
  if (returnTask.length == 0) {
    return F.returnMsg(300, '没有数据', 3);
  }
  totalIntegral += contentShareGain;
  return F.returnMsg(200, '获取成功', 3, {totalintegral: totalIntegral, 'items': returnTask});
};


/**
 * @todo API45.    获取达人分类列表
 * @param Env
 */
exports.getTalentList = function*(Env) {
  var talentList = yield F.getTalentInfo();
  if (!_.isEmpty(talentList)) {
    var returnData = [];
    for (var i in  talentList) {
      returnData.push({"talentid": talentList[i].talentid, "name": talentList[i].name});
    }
    return F.returnMsg(200, '获取成功', 3, {items: returnData});
  } else {
    return F.returnMsg(300, '获取失败', 3);
  }
};

/**
 * @todo API46.    申请达人
 * @param Env
 */
exports.askForTalent = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能操作', 3);
  }
  var act = fields.act;
  var uid = parseInt(loginStatus.uid);
  var manager = fields.manager;
  if (manager == 1 && _.v.isInt(fields.uid) && (F.isManager(loginStatus.groupid, [1, 2]))) {
    uid = fields.uid;
  }
  var talentId = fields.talentid;
  if (!F.isTalent(talentId)) {
    return F.returnMsg(400, '参数错误', 1);
  }
  var mobilePhone = fields.mobilephone;
  if (!mobilePhone) {
    return F.returnMsg(400, '手机号码为必填项', 1);
  }
  var qq = fields.qq;
  if (!qq) {
    return F.returnMsg(400, 'qq为必填项', 1);
  }
  var appReason = fields.appreason;
  if (!_.v.isLength(appReason, 1, 255)) {
    return F.returnMsg(400, '申请理由不能为空，且在255个字内', 1);
  }
  var reason = mobilePhone + "#####" + qq + "#####" + appReason;
  var userInfo = yield F.returnUserInfo(uid);
  var temp = yield F.isAlowerTalent(userInfo[0]);
  if (temp != 1 && temp != 4) {
    return F.returnMsg(400, '未能申请、审批中或已经申请成功', 1);
  }
  mysql.query('INSERT INTO mh_talent_asklog(uid,timeline,talentid,appreason) VALUES(?,UNIX_TIMESTAMP(),?,?)', [uid, talentId, reason]);
  return F.returnMsg(200, '已提交申请', 3);
};

/**
 * @todo API47.    达人排行榜
 * @param Env
 * @returns {*}
 */
exports.talentRanking = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  var talentId = fields.talentid;
  if (!F.isTalent(talentId)) {
    return F.returnMsg(400, '参数错误', 1);
  }
  var page = fields.page || 1;
  var pageSize = fields.pagesize != undefined ? parseInt(fields.pagesize) : C.threadlist.pageSize;
  var beginIndex = (page - 1) * pageSize;
  var userIdData = yield mysql.query('SELECT uid FROM mh_user_info WHERE talentid=? ORDER BY integral DESC LIMIT ?,?', [talentId, beginIndex, pageSize]);
  var userIdArr = [];
  for (var i in userIdData) {
    userIdArr.push(userIdData[i].uid);
  }
  if (userIdArr.length == 0) {
    return F.returnMsg(300, '没有数据了', 3);
  }
  var returnData = {
    pageIndex: page,
    items: []
  };
  var userInfo = yield F.returnUserInfo(userIdArr);
  for (var i in userInfo) {
    var friendStatus = false;
    if (loginStatus.status) {
      var isFriend = yield MUsers.isFriend(loginStatus.uid, parseInt(userInfo[i].uid));
      if (isFriend) {
        friendStatus = true;
      } else if (_.v.isIn(parseInt(userInfo[i].uid), C.sns.manager_uid)) {  //if (_.v.isIn(fuid, C.sns.manager_uid)){
        //判断是否系统发言用户
        friendStatus = true;
      }
    }

    var face = "";
    if (userInfo[i].hasOwnProperty('face')) {
      face = userInfo[i].face;
      face = F.generateFaceUrl(face, parseInt(userInfo[i].uid));
    }
    var vip = 0;
    var talent = "";
    var talent_level = 0;
    var talentid = 0;
    var level = F.getLevelfromIntegral(userInfo[i].integral);

    //显示达人称号
    //显示达人等级
    if (userInfo[i].talentid > 0) {// 是否达人  (VIP 无达人属性)
      talentid = userInfo[i].talentid;
      talent = F.getTalentInfo(userInfo[i].talentid).name;
      talent_level = level.talent_level; //  this.getTalentInfo(threads[i].talentid).talent_level;
    } else {
      talent = '';
      talentid = 0;
    }
    returnData.items.push({
      "uid": userInfo[i].uid,
      "nickname": userInfo[i].nickname,
      "level": userInfo[i].level,
      "friendStatus": friendStatus,
      "face": face,
      "vip": vip,
      "talent": talent,
      "talent_level": talent_level,
      "talentid": talentid
    });
  }
  return F.returnMsg(200, '获取成功', 3, returnData);
};


exports.tranPoiList = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (loginStatus.status && F.isManager(loginStatus.groupid)) {
    let poiList = yield mysql.query('SELECT poiid,name,longitude,latitude,tagid FROM mh_poi_detail');
    for (var i in poiList) {
      poiList[i].uid = poiList[i].poiid;
      F.saveUser2Mongo(poiList[i]);
      F.savePoi2Mongo(poiList[i]);
    }
  } else {
    return {};
  }
};

/**
 * @todo API48.    用户地址
 * @param Env
 */
exports.address = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能操作', 3);
  }
  let act = fields.act;
  let uid = loginStatus.uid;
  let aid = fields.aid || 0;
  if (_.v.isIn(parseInt(act), [3, 4, 5])) {
    if (aid == 0) {
      return F.returnMsg(400, '参数帖子id无效', 3)
    }
  }
  else if (act == 2) {
    aid = 0;//当新增地址信息时，忽略aid参数
  }

  if (act == 1) { //取地址列表
    let userAddressList = new mUserAddress.userAddressList();
    let ret = yield userAddressList.get(uid);
    if (parseInt(ret.error) == 0) {
      return F.returnMsg(200, ret.msg, 3, ret.data);
    } else {
      return F.returnMsg(300, ret.msg, 1);
    }
  } else if (act == 2 || act == 3) { //添加地址,修改地址(当aid<>0时，修改地址)
    let regionid = parseInt(fields.regionid);
    if (regionid < 1) return F.returnMsg(300, 'regionid 格式错误', 1);
    if (fields.address.length > 255) return F.returnMsg(300, '地址字段过长', 1);
    if (fields.mobile.length > 11) return F.returnMsg(300, '电话字段过长', 1);
    if (fields.mobile.postcode > 6) return F.returnMsg(300, '邮编字段过长', 1);
    if (fields.mobile.username > 10) return F.returnMsg(300, '收件人字段过长', 1);
    let addr = yield F.getRegionArray(regionid);
    addr['address'] = fields.address || '';
    addr['username'] = fields.username || '';
    addr['mobile'] = fields.mobile || '';
    addr['postcode'] = fields.postcode || '';
    addr['status'] = 1;

    let shippingAddress = new mUserAddress.userAddress(aid, uid, addr);
    let ret = yield shippingAddress.save();
    return F.returnMsg(200, ret.msg, 3);
  } else if (act == 4) { //删除地址
    let addr = {};
    addr['uid'] = uid;
    addr['aid'] = aid;
    let shippingAddress = new mUserAddress.userAddress(aid, uid, addr);
    let ret = yield shippingAddress.delete();
    return F.returnMsg(200, ret.msg, 3);
  } else if (act == 5) { //设置默认收货地址
    let addr = {};
    addr['uid'] = uid;
    addr['aid'] = aid;
    let shippingAddress = new mUserAddress.userAddress(aid, uid, addr);
    let ret = yield  shippingAddress.setDefaultAddress();
    return F.returnMsg(200, ret.msg, 3);
  }
};

/**
 * @todo API49.    查询用户活动状态
 * @param Env
 */
exports.UseractivityState = function*(Env) {
  let fields = Env.I;
  let actid = fields.actid || 0;
  if (actid < 0 || !parseInt(actid) > 0) {
    return F.returnMsg(400, 'actid参数只能输入整数.', 1);
  }
  let UserActivityData = yield F.get_userActivityState(Env);
  let message = {body: ''};
  let btnArray = [];
  if (UserActivityData.retcode == 0) {
    return F.returnMsg(300, '该活动不存在', 3);
  }

  let mobileCaptcha = '<center><big><strong>手机号码:' + UserActivityData['mobile'] + '</center>' +
    '<br /><center>兑换码:' + UserActivityData['captcha'] +
    '</strong></big></center>';
  let begintime = new Date(UserActivityData['begintime'] * 1000);
  let endtime = new Date(UserActivityData['endtime'] * 1000);
  let validbegintime = new Date(UserActivityData['validbegintime'] * 1000);
  let validendtime = new Date(UserActivityData['validendtime'] * 1000);

  switch (parseInt(UserActivityData.retcode)) {
    case 1://活动未开始
      message.body = '<center><big><strong>活动即将开始</strong></big></center><br />' +
        '<center>抢兑换码时间：<font color="red">' + begintime.format('yyyy-MM-dd') + '至' + endtime.format('yyyy-MM-dd') + '</font></center>';
      btnArray.push({status: 2, title: '免费领面膜', btn_act: 3});
      break;
    case 2://兑奖（领面膜）活动已结束
      message.body = '<center><big><strong>兑奖活动已经结束</strong></big></center>';
      break;
    case 3://领取验证码时间已过
      message.body = '<center><big><strong>抢兑换码活动已经结束</strong></big></center>';
      break;
    case 4://用户未登录
      //return F.returnMsg(400, '登录用户才能操作', 3);
      message.body = '<center><big><strong>活动进行中</strong></big></center>';
      btnArray.push({status: 1, title: '免费领面膜', btn_act: 3});
      break;
    case 5://用户未绑定手机
      message.body = '<center><big><strong>请先绑定手机才能领取面膜</strong></big></center>';
      btnArray.push({status: 1, title: '请先绑定手机', btn_act: 5});
      btnArray.push({status: 2, title: '免费领面膜', btn_act: 3});
      break;
    case 6://可领取验证码
      message.body = '<center><big><strong>活动进行中</strong></big></center>';
      btnArray.push({status: 1, title: '免费领面膜', btn_act: 3});
      break;
    case 7://已经兑换过礼品
      message.body = '<center><big><strong>恭喜你已经兑奖</strong></big></center><br />' +
        '<center>敬请期待下次活动</center>';
      break;
    case 8://未到兑换开始时间
      btnArray.push({status: 2, title: '请输入确认码', btn_act: 6, captcha: UserActivityData['captcha']});
      message.body = mobileCaptcha
        + '<br />未到兑奖开始时间' +
        '<br />兑奖时间：' + validbegintime.format('yyyy-MM-dd') + '至' + validendtime.format('yyyy-MM-dd');
      break;
    case 9://可以领取
      btnArray.push({status: 1, title: '请输入确认码', btn_act: 6, captcha: UserActivityData['captcha']});
      message.body = mobileCaptcha
        + '<br /><center>兑奖时间：' + validbegintime.format('yyyy-MM-dd') + '至' + validendtime.format('yyyy-MM-dd') + '</center>';
      break;
  }
  //存在该活动时，都显示查询附近的店铺
  if (parseInt(UserActivityData.retcode) > 0) {
    let btn = {status: 1, title: '查看附近门店', btn_act: 2};
    btnArray.push(btn);
  }
  if (UserActivityData.retcode > 0) {
    delete(UserActivityData.retcode);
    delete(UserActivityData.captcha);
    delete(UserActivityData.mobile);
    delete(UserActivityData.captchaid);
    UserActivityData.message = message;
    UserActivityData.btn = btnArray;
    return F.returnMsg(200, '获取成功', 3, UserActivityData);
  }
};

/**
 * @todo API50.    获取兑换码、或兑奖
 * @param Env
 */
exports.activityRedeemCode = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能操作', 3);
  }
  let UserActivityData = yield F.get_userActivityState(Env);
  let act = fields.act;
  let uid = loginStatus.uid;
  let actid = fields.actid || 0;
  let confirmationCode = fields.concode;
  let captcha = fields.captcha || 0;
  let currentDate = parseInt(new Date().getTime() / 1000);
  if (act == 2) {//兑换验证码时，验证验证码跟确认码是否符合规则
    if (!captcha || captcha.length != 6) {
      return F.returnMsg(400, '兑换码有误，请输入六位的兑换码', 1);
    }
    if (!confirmationCode || confirmationCode.length <= 2 || !_.str.startsWith(confirmationCode.toLowerCase(), 'cs')) {
      return F.returnMsg(400, '确认码有误，请检查确认码是否符合规则', 1);
    }
  }
  if (act == 1) {//获取验证码
    if (UserActivityData.retcode == 9) {
      return F.returnMsg(400, '你已经领取过兑换码，请到附近门店兑换礼品', 1);
    }
    if (UserActivityData.retcode == 6) {//当状态为6(可领取验证码)时，可领取验证码
      let captcha = F.getRandom(6);
      let orderResult = yield mysql.query('insert into mh_order(wareid,uid,actid,date,shiptype) values(' +
        '?,?,?,?,?)', [UserActivityData['wareid'], uid, actid, currentDate, 1]);
      if (orderResult.affectedRows > 0) {
        let oid = orderResult.insertId;
        let captchaResult = yield mysql.query('insert into mh_order_captcha(uid,orderid,mobile,validbegintime,validendtime,captcha) values(' +
          '?,?,?,?,?,?)', [uid, oid, UserActivityData['mobile'], UserActivityData['validbegintime'], UserActivityData['validendtime'], captcha]);
        if (captchaResult.affectedRows > 0) {
          return F.returnMsg(200, '获取成功', 3);
        }
      }
    }
    return F.returnMsg(400, '获取失败', 1);
  } else if (act == 2) {//领取产品
    if (UserActivityData.retcode == 9) {//当状态为9（到店领取），可兑换礼品
      let shopid = parseInt(confirmationCode.toLowerCase().replace('cs', ''));
      if (!shopid) {
        return F.returnMsg(400, '确认码有误，请检查', 1);
      }
      let wastonShop = yield mysql.query('select 1 from mh_watsons where wshopid=? and chnstatus=1', [shopid]);
      if (wastonShop && wastonShop.length > 0) {
        let result = yield mysql.query('update mh_order_captcha set receive=1,shopid=?,exchangetime=? where ocid=? and captcha=?', [shopid, currentDate, UserActivityData['captchaid'], captcha.toString()]);
        if (result.affectedRows > 0) {
          return F.returnMsg(200, '兑奖成功', 3);
        } else {
          return F.returnMsg(400, '您输入的兑换码有误或不存在，请检查', 1);
        }
      } else {
        return F.returnMsg(400, '确认码有误，请确认店铺编号是否正确', 1);
      }
    }
    return F.returnMsg(400, '兑奖失败', 1);
  }
};

/**
 * @todo API49b.    查询用户活动状态
 * @param Env
 */
exports.userActivityState = function*(Env) {
  let fields = Env.I;
  let actid = fields.actid || 0;
  if (actid < 0 || !parseInt(actid) > 0) {
    return F.returnMsg(400, 'actid参数只能输入整数.', 1);
  }
  let UserActivityData = yield F.get_userActivityStep(Env);
  console.log(UserActivityData.stepMsg);
};

/**
 * @todo API52.    女性生理周期管理
 * @param Env
 */
exports.menstruationInfo = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能操作', 3);
  }
  let act = parseInt(fields.act);
  let uid = loginStatus.uid;

  let mInfo = yield mysql.queryOne('SELECT menstruation FROM mh_user_info WHERE uid=?', [uid]);
  let Info = F.isJson(mInfo['menstruation']);
  if (!Info) {
    Info = {
      defaultmenstruation: {},
      menstruation: []
    };
  }

  switch (act) {
    case 1: // 提交
      if (F.isJson(fields['defaultmenstruation'])) {
        let defaultmenstruation = F.isJson(fields['defaultmenstruation']);
        if (_.isNumber(defaultmenstruation.analysisCycle) && _.isNumber(defaultmenstruation.analysisDays)) {
          Info.defaultmenstruation.analysisCycle = defaultmenstruation.analysisCycle;
          Info.defaultmenstruation.analysisDays = defaultmenstruation.analysisDays;
          mInfo = JSON.stringify(Info);
          yield mysql.queryOne('UPDATE mh_user_info set menstruation=? WHERE uid=?', [mInfo, uid]);
          return F.returnMsg(200, '成功', 3, Info);
        }
      }
      return F.returnMsg(400, '参数错误', 3);
      break;
    case 2:
      if (F.isJson(fields['menstruation'])) {
        let menstruation = F.isJson(fields['menstruation']);
        if (_.v.isDate(menstruation.analysisStart) && _.isNumber(menstruation.analysisCycle) && _.isNumber(menstruation.analysisDays)) {
          // 起始日的 Unix 时间戳
          let aStart = new Date(menstruation['analysisStart'] + ' 0:0:0 CST+800').getTime() / 1000;
          let eDate = new Date(menstruation['analysisStart'] + ' 0:0:0 CST+800');
          //eDate.addDays(menstruation.analysisCycle);
          //let n = F.dateDiff(eDate.getTime() / 1000, new Date().getTime() / 1000);
          let n = F.dateDiff(eDate.getTime(), new Date().getTime());
          if (n >= 0) { // 如果不是设置未来的日期
            menstruation['analysisStart'] = new Date(aStart * 1000).format('yyyy-MM-dd');
            let new_menstruation = [];
            for (let i in Info.menstruation) {
              let nDate = new Date(Info.menstruation[i]['analysisStart'] + ' 0:0:0 CST+800').getTime() / 1000;
              let n = F.dateDiff(aStart, nDate);
              if (n < -14 || n > 14) {
                new_menstruation.push(Info.menstruation[i])
              }
            }

            new_menstruation.push({
              analysisStart: menstruation.analysisStart,
              analysisCycle: menstruation.analysisCycle,
              analysisDays: menstruation.analysisDays
            });
            Info.menstruation = _.sortBy(new_menstruation, 'analysisStart');
            mInfo = JSON.stringify(Info);
            yield mysql.queryOne('UPDATE mh_user_info set menstruation=? WHERE uid=?', [mInfo, uid]);
            return F.returnMsg(200, '成功', 3, Info);
          } else {
            return F.returnMsg(400, '不能设置未来的日期', 1, Info);
          }
        }
      }
      return F.returnMsg(400, '参数错误', 3);
      break;
    case 3:
      return F.returnMsg(200, '成功', 3, Info);
      break;
    default:
  }

};

/**
 * @todo API53.    用户帖子类别信息
 * @param Env
 */
exports.userCategoryInfo = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  let act = parseInt(fields.act);
  let uid = loginStatus.uid;
  let categorylist = fields.categorylist;

  if (act == 4 || act == 3) {//3:获取最近使用，已关注及全部帖子类别；4:删除并重建用户订阅帖子类别
    if (!loginStatus.status) {
      return F.returnMsg(401, '登录用户才能操作', 3);
    }
  }
  var pinCidArr = [];
  if (act == 4) {
    if (!categorylist || categorylist.trim().length == 0) {
      return F.returnMsg(401, '必须传入关注帖子列表参数', 3);
    } else if (parseInt(categorylist) < 0) {//当返回-1时，表示没有关注任何类别，删除已经关注的类别
      let ret = yield mysql.query('delete from mh_pincategory where uid=?', uid);
      if (ret.affectedRows > 0) {
        return F.returnMsg(200, '操作成功', 3);
      }
    }
    else {
      try {
        let childCategory = yield mysql.query('select 1 from mh_thread_category where pcid=0 and ctype=0 and cid IN (' + categorylist + ')');
        if (childCategory && childCategory.length > 0) {
          return F.returnMsg(200, '传入的类别编号包含一级类别，不能订阅一级类别，请检查', 3);
        }
      } catch (e) {
        return F.returnMsg(200, '传入的关注帖子列表参数有误，请检查', 3);
      }
    }
    //删除已经关注的帖子类别
    yield mysql.query('delete from mh_pincategory where uid=?', uid);
    //var categoryIdArr = categorylist.split(',').sort();
    var categoryIdArr = categorylist.split(',');
    var uniqueCategoryIdArr = _.uniq(categoryIdArr, true);
    //var uniqueCategoryIdArr = [];
    //for (let i in categoryIdArr) {
    //    i = parseInt(i);
    //    if (categoryIdArr[i] == categoryIdArr[i + 1]) {
    //        continue;
    //    }
    //    uniqueCategoryIdArr[uniqueCategoryIdArr.length] = categoryIdArr[i];
    //}
    var errorcategoryArr = [];
    for (var i = uniqueCategoryIdArr.length - 1; i >= 0; i--) {
      let sql = ' where exists(select 1 from mh_thread_category where cid =' + parseInt(uniqueCategoryIdArr[i]) + ' and pcid<>0 and pcid<>39 and ctype=1)';
      let ret = yield mysql.query('insert into mh_pincategory(uid,cid,sort,timeline) select ?,?,?,UNIX_TIMESTAMP() from dual ' + sql, [uid, parseInt(uniqueCategoryIdArr[i]), i + 1]);
      if (ret.affectedRows == 0) {
        errorcategoryArr.push(uniqueCategoryIdArr[i]);
      }
    }
    if (0 == errorcategoryArr.length) {
      return F.returnMsg(200, '关注成功', 3);
    } else {
      return F.returnMsg(200, '以下类别id[' + errorcategoryArr.join(',') + ']在数据库不存在，请检查', 3);
    }
  }

  let categoryData = {};
  if (loginStatus.status) {
    if (act == 3) {
      //获取最近使用的帖子类别
      let recentCategory = yield mysql.queryOne('select mui.lastestcategories from mh_user_info  mui where uid=? ', [loginStatus.uid]);
      if (recentCategory && recentCategory['lastestcategories'] != '') {
        let recentCategoryData = yield mysql.query('select cid,name,latest from mh_thread_category where `status`=1 and threadstatus=1 and cid in (' + recentCategory['lastestcategories'] + ')');
        if (recentCategoryData && recentCategoryData.length > 0) {
          if (recentCategory['lastestcategories'].indexOf(',') == -1)
            categoryData.recent = recentCategoryData;
          else {
            let arrRecent = [];
            for (let i in recentCategory['lastestcategories'].split(',')) {
              for (let j in recentCategoryData) {
                if (recentCategory['lastestcategories'].split(',')[i] == recentCategoryData[j]['cid']) {
                  let recentData = {};
                  recentData.cid = recentCategoryData[j]['cid'];
                  recentData.name = recentCategoryData[j]['name'];
                  recentData.latest = recentCategoryData[j]['latest'];
                  arrRecent.push(recentData);
                  break;
                }
              }
            }
            categoryData.recent = arrRecent;
          }
        }
      }
    }

    //获取已经关注的帖子类别
    let pinCategoryData = yield mysql.query('select mp.cid,mtc.name,mtc.latest,p_mtc.cid as pid from mh_pincategory mp INNER JOIN mh_thread_category mtc on mp.cid=mtc.cid and mtc.`status`=1 ' +
      'inner join mh_thread_category p_mtc on p_mtc.cid=mtc.pcid and p_mtc.ctype=0 ' +
      'where mp.uid=? order by mp.sort', [loginStatus.uid]);
    categoryData.pin = pinCategoryData;
  }
  for (let i in categoryData.pin) {
    pinCidArr.push(categoryData.pin[i].cid);
  }
  if (act == 2 || act == 3) {
    let arrWholeCategory = [];
    let parentId = [];
    let wholeCategoryData = yield mysql.query('select mtc1.name as p_name,mtc1.cid as p_cid,mtc2.name as child_name,mtc2.cid as child_cid,mtc2.pcid,mtc2.latest ' +
      'from mh_thread_category mtc1 inner join mh_thread_category mtc2 on mtc1.cid=mtc2.pcid and mtc1.ctype=0 and mtc2.ctype=1 and mtc2.status=1 where mtc2.threadstatus<>2 and mtc2.pcid<> ? order by mtc1.sort,mtc2.sort', [C.threadCategory.client_filter_parent_category]);
    for (var item in wholeCategoryData) {
      let currentCategoryData = {};
      currentCategoryData.pid = wholeCategoryData[item]['p_cid'];
      currentCategoryData.pname = wholeCategoryData[item]['p_name'];
      let curentChildCategory = [];
      //判断是否已经包含在结果数组中
      if (parentId.indexOf(currentCategoryData.pid) > -1) {
        continue;
      }
      for (var item1 in wholeCategoryData) {
        if (parseInt(wholeCategoryData[item]['p_cid']) == parseInt(wholeCategoryData[item1]['pcid']))
          curentChildCategory.push(
            {
              child_id: wholeCategoryData[item1]['child_cid'],
              child_name: wholeCategoryData[item1]['child_name'],
              hasPin: pinCidArr.indexOf(parseInt(wholeCategoryData[item1]['child_cid'])) > -1 ? 1 : 0,
              latest: wholeCategoryData[item1]['latest']
            }
          );
      }
      currentCategoryData.child = curentChildCategory;
      arrWholeCategory.push(currentCategoryData);
      parentId.push(currentCategoryData.pid);
    }
    categoryData.whole = arrWholeCategory;
  }
  if (!categoryData.pin && act == 1) {
    return F.returnMsg(300, '数据不存在', 3);
  }
  return F.returnMsg(200, '获取成功', 3, categoryData);
};

/**
 * @todo API55.    用户美容日记贴API
 * @param Env
 */
exports.userDailyOperation = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  let act = parseInt(fields.act) || 0;
  let tid = parseInt(fields.tid) || 0;
  let before = parseInt(fields.before) || 0;//为0时为设置现在图封面，为1时为过去图封面
  let title = fields.title || '';
  let imgstr_before = fields.imgstrbefore || '';
  let imgstr_after = fields.imgstrafter || '';
  let manager = fields.manager || '';
  let page = fields.page || 1;
  let pageSize = fields.pagesize != undefined ? parseInt(fields.pagesize) : C.threadlist.pageSize;
  let beginIndex = (page - 1) * pageSize;

  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能操作', 3);
  }
  if (tid == 0 && _.v.isIn(act, [1, 2])) {
    return F.returnMsg(400, '请选传入美容日记帖子id', 3);
  }
  switch (act) {
    case 1://获取美容日记所有的图片
      var imgArr = [];
      if (manager && manager == 1 && F.isManager(loginStatus.groupid)) {
        var imgData = yield mysql.query('SELECT mt.tid,mt.validimg,mt.imagestring from mh_thread mt ' +
          'where (mt.fid=? or mt.tid=?) and mt.STATUS=1 order by mt.tid desc', [tid, tid]);
        var imgCoverData = yield mysql.queryOne('SELECT mtd.imageAfter,mtd.imageBefore from mh_thread_extend mtd INNER JOIN mh_thread mt ' +
          'on mtd.tid=mt.tid  WHERE mt.type>0 and mt.status=1 and mt.tid=?', [tid]);
      } else {
        var imgData = yield mysql.query('SELECT mt.tid,mt.validimg,mt.imagestring from mh_thread mt ' +
          'where (mt.fid=? or mt.tid=?) and mt.STATUS=1 and mt.uid=? order by mt.tid desc', [tid, tid, loginStatus.uid]);
        var imgCoverData = yield mysql.queryOne('SELECT mtd.imageAfter,mtd.imageBefore from mh_thread_extend mtd INNER JOIN mh_thread mt ' +
          'on mtd.tid=mt.tid  WHERE mt.type>0 and mt.uid=? and mt.status=1 and mt.tid=?', [loginStatus.uid, tid]);
      }
      if (imgCoverData) {
        var selectedImg = {
          imgstr: imgCoverData['imageAfter'],
          imgurl: _.isEmpty(imgCoverData['imageAfter']) ? '' : imgRule.str2imgURI(imgCoverData['imageAfter'])[0].imgURI + C.upyun.suffix
        };
        if (before == 1) {
          selectedImg = {
            imgstr: imgCoverData['imageBefore'],
            imgurl: _.isEmpty(imgCoverData['imageBefore']) ? '' : imgRule.str2imgURI(imgCoverData['imageBefore'])[0].imgURI + C.upyun.suffix
          };
        }
      } else {
        return F.returnMsg(400, '获取失败,你当前的权限不足，请检查', 3);
      }
      for (let imgRecord of imgData) {
        var tempData = imgRecord['validimg'].split(',');
        var imgstringArr = imgRecord['imagestring'].split(',');
        for (let i in tempData) {
          let imgIndex = tempData[i].split('-');
          if (imgIndex[1] == 1) {//有效图片
            var imgStr = imgstringArr[i];
            var imgUrl = imgRule.str2imgURI(imgStr)[0].imgURI + C.upyun.suffix;
            imgArr.push({imgstr: imgStr, imgurl: imgUrl, selected: imgStr == selectedImg.imgstr ? 1 : 0});
          } else continue;
        }
      }
      return F.returnMsg(200, '获取成功', 3, {tid: tid, selectedImg: selectedImg, images: imgArr});
    case 2://设置日记帖专有信息
      var updateThreadCache = {};
      var updateSQL = 'update mh_thread_extend set tid=? ';
      var valArr = [tid];
      if (imgstr_before.trim() != '') {
        updateSQL += ',imageBefore=?';
        valArr.push(imgstr_before);
        updateThreadCache.imageBefore = imgRule.str2imgURI(imgstr_before)[0].imgURI + C.upyun.suffix;
      }
      if (imgstr_after.trim() != '') {
        updateSQL += ',imageAfter=?';
        valArr.push(imgstr_after);
        updateThreadCache.imageAfter = imgRule.str2imgURI(imgstr_after)[0].imgURI + C.upyun.suffix;
      }
      if ((!_.v.isLength(_.v.trim(title), 1, 15)) && _.v.trim(title).length > 0) {
        return F.returnMsg(400, '日记标题只能在15个字符内', 1);
      } else if (_.v.isLength(_.v.trim(title), 1, 15)) {
        updateSQL += ',title=?';
        valArr.push(_.v.trim(title));
        updateThreadCache.title = title;
      }
      //手术价钱 price
      var price = fields.price || 0;
      if (price != 0) {
        if (!_.v.isFloat(price)) {
          return F.returnMsg(400, '价钱输入有误，请修改', 1);
        } else if (parseFloat(price) > 99999999) {
          return F.returnMsg(400, '价钱字段超长，请修改', 1);
        }
        else {
          updateSQL += ',operationPrice=?';
          valArr.push(price);
          updateThreadCache.operationPrice = price;
        }
      }

      //手术日期 firstDate
      var firstDate = fields.firstDate || '';
      if (firstDate != '') {
        if (!_.v.isDate(firstDate)) {
          return F.returnMsg(400, '手术日期输入格式有错，请修改', 1);
        } else {
          firstDate = parseInt(new Date(firstDate + ' 0:0:0 CST+800').getTime() / 1000);
          updateSQL += ',firstDate=?';
          valArr.push(firstDate);
          updateThreadCache.firstDate = firstDate;
        }
      }

      //专家名称 doctor
      var doctor = fields.doctor || '';
      if ((!_.v.isLength(_.v.trim(doctor), 1, 10)) && _.v.trim(doctor).length > 0) {
        return F.returnMsg(400, '专家名称只能在10个字符内', 1);
      } else if (_.v.isLength(_.v.trim(doctor), 1, 10)) {
        updateSQL += ',doctor=?';
        valArr.push(_.v.trim(doctor));
        updateThreadCache.doctor = doctor;
      }

      //机构id shopid  机构名称 shopName
      var shopid = fields.shopid || 0;
      if (shopid > 0) {
        var ret = yield o2o_F.o2oGetShopInfoByShopId(shopid);
        if (!(parseInt(ret['result']['error']) == 1 || ret.status == 400)) {
          updateSQL += ',shopid=?';
          valArr.push(shopid);
          updateThreadCache.shopid = shopid;

          updateSQL += ',shopName=?';
          valArr.push(ret['result'].name);
          updateThreadCache.shopName = ret['result'].name;
        }
      }
      var operationTags = fields.operationTags || '';
      operationTags = operationTags.split(',');
      if (operationTags.length > 10) {
        return F.returnMsg(400, '至多输入十个项目标签', 1);
      }
      if (operationTags.length > 0 && operationTags != '') {
        var operation_detail_array = yield o2o_F.o2oGetOperationTagsByArray(operationTags);
        if (!_.v.isLength(operation_detail_array.length, 1, 10)) {
          return F.returnMsg(400, '传入的项目标签在系统中未能找到', 1);
        } else if (_.v.isLength(operation_detail_array.length, 1, 10)) {
          var categoryId = operation_detail_array[0].threadCategory;
          var categoryName = operation_detail_array[0].name;
          mysql.query('update mh_thread set cid=? where tid=?', [categoryId, tid]);
          updateThreadCache.cid = categoryId;
          updateThreadCache.categoryname = categoryName;

          //先执行更新标签使用次数,再删除

          var tagsData = yield mysql.queryOne('select GROUP_CONCAT(tagsid) as tags from mh_thread_tags where tid=? and tagstype = 6', [fields.tid]);
          if (tagsData && tagsData['tags']) {
            yield mysql.query('delete from mh_thread_tags where tid=? and tagstype = 6', [fields.tid]);
            var tagArray = tagsData['tags'].split(',');
            for (var i in tagArray) {
              mysql.query('update mh_tags set tagcount=tagcount-1 where tagid=?', [tagArray[i]]);
            }
          }
          for (var tag of operation_detail_array) {
            yield mysql.query('INSERT INTO mh_thread_tags(tid,tagsid,tagstype,tagstitle,imgindex) VALUES(?,?,?,?,?)', [tid, tag.code, 6, tag.name, -1]);
          }
          //如果更新了帖子的项目，则删掉主贴缓存
          //删除主题帖缓存
          var key = C.redisPre.thread_info;
          key = _.str.sprintf(key, parseInt(tid));
          var temp = yield F.redisCo.EXISTS(key);
          if (temp == 1) {
            F.redisClient.DEL(key);
          }
        }
      }

      updateSQL += ' where tid=?';
      valArr.push(tid);
      //var updateImgResult = yield mysql.query('update mh_thread_extend set imageBefore=?,imageAfter=?,title=? where tid=?', [imgb4Url, imgAfterUrl, title, tid]);
      var updateImgResult = yield mysql.query(updateSQL, valArr);
      if (updateImgResult.affectedRows > 0) {
        yield F.updateThreadCache(parseInt(tid), updateThreadCache);//更新帖子缓存
        return F.returnMsg(200, '保存成功', 1);
      } else {
        return F.returnMsg(400, '保存失败', 1);
      }
    case 3://获取用户已消费并且没写美容日记帖的订单
      var _o2oServiceApi = require('../common/o2oServiceApi');
      var o2oServiceApi = new _o2oServiceApi;
      var orderList = yield  o2oServiceApi.post('order', 'list', 1, {act: 1, uid: loginStatus.uid});
      var hasConsumedOrder = _.filter(orderList['result'], function (order) {
        return order.has_consumed_number > 0;
      });
      if (hasConsumedOrder.length == 0)
        return F.returnMsg(300, '你还没有已消费的订单', 3);
      else {
        var didNotWriteDailyOrder = _.filter(hasConsumedOrder, function (order) {
          return order.daily_thread_id == 0;
        });
        if (didNotWriteDailyOrder.length == 0) {
          return F.returnMsg(300, '你已经对所有已消费订单创建过日记，请选择对应的订单进行更新日记操作.', 3);
        } else {
          for (let order of didNotWriteDailyOrder) {
            order.cid = 20;//@todo write a function to get thread category based on ware.category
            order.threadCategory = '护肤';
          }
          if(C.env == 'production'){
            didNotWriteDailyOrder = [];
          }
          return F.returnMsg(200, '获取成功', 3, didNotWriteDailyOrder);
        }
      }
    case 4://获取登陆者的美容日记贴封面
      var dailyThreadData = yield mysql.query('SELECT t.tid,mte.title,mte.firstDate FROM mh_thread t LEFT JOIN mh_thread_extend mte ON t.tid=mte.tid WHERE t.uid=? and t.type>0 and t.status=1 and t.fid=0 ORDER BY t.tid DESC LIMIT ?,?', [parseInt(loginStatus.uid), beginIndex, pageSize]);
      if (dailyThreadData && dailyThreadData.length > 0) {
        return F.returnMsg(200, '获取成功', 3, {items: dailyThreadData});
      } else {
        return F.returnMsg(300, '已经没有数据了', 3);
      }

  }
};

/**
 API58 绑定或者解绑第三方账号
 */
exports.bindUserAccount = function*(Env) {
  let fields = Env.I;
  let act = fields.act;//1：绑定； 2：解绑
  let loginStatus = fields.loginStatus;
  let mediaType = fields.mediatype;//媒介类型 1 QQ 4 微信
  let accessToken = fields.accesstoken;//接口调用凭证
  let openId = fields.openid;//app唯一识别码
  let expiresIn = fields.expires_in || 0;//过期时间(秒)
  let unionid = '';//用户统一标识
  let user3rdBingInfo = {};
  let status = 1;
  if (act == 2) {//解绑
    status = 0;
  }

  if (!loginStatus.status) {
    return F.returnMsg(401, '登录用户才能操作', 1);
  }
  user3rdBingInfo = yield F.get3rdBindInformation(loginStatus.uid);
  if (act == 3) {
    return F.returnMsg(200, '成功', 3, user3rdBingInfo);
  }
  if (!_.v.isIn(parseInt(mediaType), [1, 4])) {
    return F.returnMsg(400, '传递的媒体参数错误', 1);
  }

  if (act == 1) {//绑定第三方账号
    let mediaUserData = yield F.oauthLogin(mediaType, accessToken, openId);//尝试取得用户信息，成功说明传过来的票据正确。
    mediaUserData = JSON.parse(mediaUserData);
    switch (mediaType) {
      case "1"://QQ
        if (mediaUserData.ret != 0) {//非0表示拿不到信息
          return F.returnMsg(300, '授权失败', 1);
        }
        break;
      case "4"://微信
        if (mediaUserData.errcode != undefined && mediaUserData.errcode == 40003) {//微信返回状态码 40003代表失败
          return F.returnMsg(300, '授权失败', 1);
        } else {
          unionid = mediaUserData.unionid;
        }
        break;
      default:
        return F.returnMsg(400, '传递的参数错误', 1);
        break;
    }
    let userData = yield mysql.query('SELECT mut.*,mu.groupid,mu.nickname,face,mobile,IFNULL(`password`,\'\')!=\'\' as hasPassword FROM mh_users_token mut INNER JOIN mh_user mu ON mut.uid=mu.uid WHERE mut.mediatype=? and mut.openid=?', [mediaType, openId]);
    if (userData.length > 0) {//存在数据则绑定到当前登录的瓷肌号
      if (act == 1) {
        if (loginStatus.uid == userData[0].uid) {
          if (userData[0].status == 1) {
            return F.returnMsg(200, '你已绑定该账号', 1);
          } else {
            let ret = yield mysql.query('update mh_users_token set `status`= ? where uid=? and mediatype=?', [status, loginStatus.uid, mediaType]);
            if (ret.affectedRows > 0) {
              user3rdBingInfo = yield F.get3rdBindInformation(loginStatus.uid);
              return F.returnMsg(200, '绑定成功', 1, user3rdBingInfo);
            }
          }
        } else {
          return F.returnMsg(300, '操作失败，此账号已被绑定其他瓷肌账号', 3);
        }
      }
    } else {//不存在则绑定到当前登录账号
      expiresIn = F.timestamp() + parseInt(expiresIn);
      let ret = yield mysql.query('INSERT INTO mh_users_token(uid,mediatype,openid,timeline,access_token,expires_in,unionid,media_data) VALUES(?,?,?,UNIX_TIMESTAMP(),?,?,?,?)', [loginStatus.uid, mediaType, openId, accessToken, expiresIn, unionid, JSON.stringify(mediaUserData)]);
      if (ret.affectedRows > 0) {
        user3rdBingInfo = yield F.get3rdBindInformation(loginStatus.uid);
        return F.returnMsg(200, '绑定成功', 1, user3rdBingInfo);
      } else {
        return F.returnMsg(200, '绑定失败', 1);
      }
    }
  } else if (act == 2) {//解绑第三方账号
    if (user3rdBingInfo.boundAccount == 1) {
      return F.returnMsg(300, '绑定失败，必须保留一种登录方式', 1);
    }
    let userData = yield mysql.query('SELECT mut.*,mu.groupid,mu.nickname,face,mobile,IFNULL(`password`,\'\')!=\'\' as hasPassword FROM mh_users_token mut INNER JOIN mh_user mu ON mut.uid=mu.uid WHERE mut.mediatype=? AND mu.uid=? and mut.status=1', [mediaType, loginStatus.uid]);
    if (userData.length && userData.length > 0) {
      let ret = yield mysql.query('update mh_users_token set `status`= ? where uid=? and mediatype=?', [status, loginStatus.uid, mediaType]);
      if (ret.affectedRows > 0) {
        user3rdBingInfo = yield F.get3rdBindInformation(loginStatus.uid);
        return F.returnMsg(200, '解绑成功', 1, user3rdBingInfo);
      }
    } else {
      return F.returnMsg(300, '解绑失败，系统未能找到对应的账号', 1);
    }
  }
};
/**
 * @todo 瓷肌二维码鉴别
 * @param Env
 * fields.url APP传递过来的url地址
 */
exports.ck2dcode = function*(Env) {
  let fields = Env.I;
  let loginStatus = fields.loginStatus;
  let url = typeof(fields.url) != 'undefined' ? fields.url : '';
  let identification_object = {};
  //let reg = /http:\/\/cjm\.so\/f\/(\d+)$/ig;
  let barcode_db = [
    {
      id: 1,
      pname: "甲骨文识别码",
      reg: /http:\/\/cjm\.so\/f\/(\d+)$/ig
    },
    {
      id: 2,
      pname: "淘宝识别码",
      reg: /http:\/\/s\.tb\.cn\/2\/(.+)$/ig
    }
  ];
  for (let code of barcode_db) {
    if (code.reg.test(url)) {
      identification_object.urlType = code.id;
      identification_object.url = url;
      identification_object.code = _.escape(RegExp.$1);
      break;
    }
  }
  if (identification_object.urlType == undefined) {
    return F.returnMsg(400, '非瓷肌、瓷妆产品有效码', 1);
  }

  /*
   if (reg.test(url) && parseInt(RegExp.$1) > 0) {
   //code = parseInt(RegExp.$1);
   code = RegExp.$1;
   } else {
   return F.returnMsg(400, '非瓷肌产品有效码', 1);
   }
   let returnUrl = 'http://q.chinaskin.cn/ciji/?code=' + code;*/
  let device_id = fields['device_id']['device_id'] || '';
  let device_id_type = fields['device_id']['type'] || 0;
  let uid = 0;
  let mobile = 0;
  //检查是否登录
  if (loginStatus.status) {
    uid = parseInt(loginStatus.uid);//获取uid;
    let mobileInfo = yield F.userMobile(uid);
    if (mobileInfo.length > 0) {
      mobile = mobileInfo[0]['mobile'] || 0;
    }
  }
  //数据库入库
  var insertInfo = yield mysql.query('INSERT INTO mh_two_dimension_identification(uid,mobile,code,device_id,device_type,timeline,url_type) ' +
    'VALUES(?,?,?,?,?,UNIX_TIMESTAMP(),?)', [uid, mobile, identification_object.code, device_id, device_id_type, identification_object.urlType]);
  if (insertInfo && insertInfo.affectedRows > 0) {
    return F.returnMsg('200', '验证条件通过！', 3, {returnUrl: identification_object.url});
  } else {
    return F.returnMsg(400, '操作异常！', 3);
  }
};

/**
 * @todo API60，APP端随机抽奖API
 * @param Env
 */
exports.randomGit = function*(Env) {
  let fields = Env.I;
  let act = fields.act;
  if (act == 3) {//查询最后20条抽奖历史，免登陆
    let git_history = yield mysql.query('SELECT mu.nickname,mugh.git,timeline from mh_user_git_history mugh INNER JOIN mh_user mu on mu.uid=mugh.uid ORDER BY mugh.ugh_id DESC  LIMIT 0,20 ');
    if (git_history && git_history.length > 0) {
      return F.returnMsg(200, '成功', 1, git_history);
    } else {
      return F.returnMsg(300, '没有数据了', 1);
    }
  } else if (_.v.isIn(act, [4, 5])) {//4获取用户当日抽奖状态,5获取用户当日兑奖状态
    return yield F.get_userGitActivityState(Env);
  }

  let loginStatus = fields.loginStatus;
  if (!loginStatus.status) {
    return F.returnMsg(400, '抽奖前请先登录！', 3);
  } else {
    if (act == 1) {//用户抽奖程序
      Env.I.act = 4;
      let result = yield F.get_userGitActivityState(Env);
      if (result.retcode != 6) {
        return F.returnMsg(300, result.retmsg, 1, result);
      }
      let date_now = new Date(new Date().format('yyyy-MM-dd'));
      let date_now_str = date_now.getFullYear() + "-" + (date_now.getMonth() + 1) + "-" + date_now.getDate();
      let waston_status = 0;
      let waston_status_data = yield mysql.query('SELECT 1 from mh_region_status where region_id=? and watson_status=1', [loginStatus.city_id]);
      if (waston_status_data && waston_status_data.length > 0) {
        waston_status = 1;
      }
      let rand_int = parseInt(Math.random() * 10000);
      let git = yield F.redisCo.gitrandom(3, date_now_str, waston_status, rand_int);
      if (git > -2) {
        let ret = yield mysql.query('INSERT into mh_user_git_history(uid,date,git,timeline) VALUES(?,?,?,UNIX_TIMESTAMP())', [loginStatus.uid, date_now_str, git]);
        if (ret.affectedRows > 0 && git > -1) {
          return F.returnMsg(200, '抽奖成功！', 1, {git: git});
        } else {
          return F.returnMsg(200, '当日奖品已抽完，明天请早！', 1);
        }
      }
    } else if (act == 2) {//查询用户抽奖历史
      let git_history = yield mysql.query('SELECT git,timeline from mh_user_git_history mugh where mugh.uid=? and mugh.git>-1 ORDER BY ugh_id DESC', [loginStatus.uid]);
      if (git_history && git_history.length > 0) {
        let result = {captcha: 10000 + loginStatus.uid};
        result.git_history = git_history;
        return F.returnMsg(200, '成功', 1, result);
      } else {
        return F.returnMsg(300, '没有数据了', 1);
      }
    } else if (act == 6) { //领取产品
      Env.I.act = 5;
      let result = yield F.get_userGitActivityState(Env);
      if (result.retcode != 6) {
        return F.returnMsg(300, result.retmsg, 1);
      }
      let shopid = fields.shopid || '';
      if (shopid == '' || !_.v.isInt(shopid)) {
        return F.returnMsg(400, '输入的店编码有误，请检查', 1);
      }

      let wastonShop = yield mysql.query('select 1 from mh_watsons where wshopid=? and chnstatus=1', [shopid]);
      if (wastonShop && wastonShop.length > 0) {
        let currentDate = parseInt(new Date().getTime() / 1000);
        let result = yield mysql.query('INSERT INTO mh_order_captcha (uid,orderid,captcha,shopid,receive,exchangetime) ' +
          'SELECT uid,ugh_id,10000+uid as captcha,?,1,? from mh_user_git_history  where ugh_id =(SELECT ugh_id from mh_user_git_history where uid=? ORDER BY git,ugh_id LIMIT 0,1)', [shopid, currentDate, loginStatus.uid]);
        if (result.affectedRows > 0) {
          return F.returnMsg(200, '兑奖成功', 3);
        } else {
          return F.returnMsg(400, '您输入的兑换码有误或不存在，请检查', 1);
        }
      } else {
        return F.returnMsg(400, '确认码有误，请确认店铺编号是否正确', 1);
      }
    }
  }
};

/**
 * @todo API61 获取瓷肌商城用户信息
 * @param Env
 */
exports.getUserInfoH5 =function*(Env){
  let fields = Env.I;
  let act = parseInt(fields.act);
  let H5ver =fields.H5ver==undefined?1:parseInt(fields.H5ver);

  if(!act || !_.v.isIn(act,[1,2])){
    return  F.returnMsg(300, '获取失败', 1);
  }

  if(H5ver==1){
        let returnData={};
        let loginStatus = fields.loginStatus;
        if (!loginStatus.status){
           return F.returnMsg(200, '登录用户才能操作', 3,{"userinfo":"{}"});
        } else {
           let uid = parseInt(loginStatus.uid) || 68;
           returnData.uid =uid;
           let userAddressList = new mUserAddress.userAddressList();
           let ret = yield userAddressList.get(uid);
           console.log(ret);
            if(parseInt(ret.error) == 0 && ret.data.shippingAddress.length>0) {
                 //获取默认购物地址
                 let defaultAddress=_.filter(ret.data.shippingAddress, function (addressObj) {
                    return parseInt(addressObj.aid) == parseInt(ret.data.defaultAddress);
                 });
                 defaultAddress = defaultAddress.length>0?defaultAddress[0] : ret.data.shippingAddress[0];
                 returnData.name =defaultAddress.username;
                 returnData.mobile =defaultAddress.mobile;
                 returnData.address =_.str.trim(defaultAddress.province+defaultAddress.city+defaultAddress.district+defaultAddress.street+defaultAddress.address);
            }else{
                let userInfo =yield F.returnUserInfo(uid);
                //console.log(userInfo[0]);
                returnData.name= userInfo[0]['name'];
                returnData.mobile =userInfo[0]['mobile'];
                returnData.address=userInfo[0]['city'];
            }
          return  F.returnMsg(200, '获取成功', 3,{"userinfo":slashes.add(JSON.stringify(returnData))});
        }
  }
  return  F.returnMsg(300, '获取失败', 1);
};
